Skip to content

Commit

Permalink
player map stats
Browse files Browse the repository at this point in the history
  • Loading branch information
TsFreddie committed Jan 17, 2025
1 parent 9712804 commit 00977f4
Show file tree
Hide file tree
Showing 9 changed files with 315 additions and 153 deletions.
2 changes: 1 addition & 1 deletion src/lib/components/Modal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<!-- svelte-ignore a11y_click_events_have_key_events, a11y_no_noninteractive_element_interactions -->
<dialog
class="fixed z-50 mx-auto overflow-visible border-none bg-transparent text-slate-300 shadow-lg backdrop:bg-black/60"
class="fixed z-50 overflow-visible border-none bg-transparent text-slate-300 shadow-lg backdrop:bg-black/60"
bind:this={dialog}
onclose={() => (show = false)}
onclick={(e) => {
Expand Down
5 changes: 3 additions & 2 deletions src/lib/components/TeeRender.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@
loadingSkin = 'default';
}
} else {
skin = useDefault ? DEFAULT_SKIN : X_SPEC_SKIN;
loadingSkin = 'default';
skin = X_SPEC_SKIN;
loadingSkin = 'cancelled';
}
};
Expand Down Expand Up @@ -157,6 +157,7 @@
});
$effect(() => {
url;
name;
requestAnimationFrame(updateSkin);
});
Expand Down
62 changes: 62 additions & 0 deletions src/lib/ddnet/searches.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
export const checkMapName = (name: string, search: string) => {
if (!search) {
return true;
}

let mapInitial = '';
let mapNameNoSeparator = '';
let prevIsUpper = false;
let prevIsSeparator = true;
for (let i = 0; i < name.length; i++) {
const char = name[i];
const isUpper = !!char.match(/[A-Z]/);
const isLetter = isUpper || char.match(/[a-z]/);
const isSeparator = char == '-' || char == '_' || char == ' ';
const isNumber = char.match(/[0-9]/);
if (isUpper) {
if (!prevIsUpper || prevIsSeparator) {
mapInitial += char;
}
} else if (isLetter) {
if (prevIsSeparator) {
mapInitial += char;
}
} else if (isNumber) {
mapInitial += char;
}
prevIsUpper = isUpper;
prevIsSeparator = isSeparator;
if (!isSeparator) {
mapNameNoSeparator += char;
}
}

const mapName = name.toLowerCase();
const searchTextLower = search.toLowerCase();
return (
mapInitial.toLowerCase() == searchTextLower ||
mapNameNoSeparator.toLowerCase().includes(searchTextLower) ||
mapName.includes(searchTextLower)
);
};

export const checkMapper = (mapper: string, search: string) => {
if (!search) {
return true;
}

const mapperString = mapper || '不详';

if (search.startsWith('"') && search.endsWith('"')) {
// exact match
const mappers = (mapperString as string)
.split(',')
.flatMap((mapper) => mapper.split('&'))
.map((mapper) => mapper.trim());

search = search.slice(1, -1).toLowerCase();
return mappers.some((mapper) => mapper.toLowerCase() == search);
}

return mapperString.toLowerCase().includes(search.toLowerCase());
};
49 changes: 4 additions & 45 deletions src/lib/server/bots/handlers/maps.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,9 @@
import { mapType, numberToStars } from '$lib/ddnet/helpers';
import { checkMapName } from '$lib/ddnet/searches';
import { encodeAsciiURIComponent } from '$lib/link';
import { maps, type MapList } from '$lib/server/fetches/maps';
import type { Handler } from '../protocol/types';

const checkMapName = (map: any, search: string) => {
if (!search) {
return true;
}

let mapInitial = '';
let mapNameNoSeparator = '';
let prevIsUpper = false;
let prevIsSeparator = true;
for (let i = 0; i < map.name.length; i++) {
const char = map.name[i];
const isUpper = char.match(/[A-Z]/);
const isLetter = isUpper || char.match(/[a-z]/);
const isSeparator = char == '-' || char == '_' || char == ' ';
const isNumber = char.match(/[0-9]/);
if (isUpper) {
if (!prevIsUpper || prevIsSeparator) {
mapInitial += char;
}
} else if (isLetter) {
if (prevIsSeparator) {
mapInitial += char;
}
} else if (isNumber) {
mapInitial += char;
}
prevIsUpper = isUpper;
prevIsSeparator = isSeparator;
if (!isSeparator) {
mapNameNoSeparator += char;
}
}

const mapName = map.name.toLowerCase();
const searchTextLower = search.toLowerCase();
return (
mapInitial.toLowerCase() == searchTextLower ||
mapNameNoSeparator.toLowerCase().includes(searchTextLower) ||
mapName.includes(searchTextLower)
);
};

export const handleMaps: Handler = async ({ reply, fetch, args }) => {
const mapName = args.trim();
if (!mapName) {
Expand All @@ -55,10 +14,10 @@ export const handleMaps: Handler = async ({ reply, fetch, args }) => {
});
}

const mapData: any[] = await maps.fetch();
const mapData = await maps.fetch();

const filteredMaps = mapData.filter((map: any) => {
return checkMapName(map, mapName);
const filteredMaps = mapData.filter((map: (typeof mapData)[0]) => {
return checkMapName(map.name, mapName);
});

if (filteredMaps.length == 0) {
Expand Down
68 changes: 3 additions & 65 deletions src/routes/ddnet/maps/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import { ddnetDate, mapType, numberToStars } from '$lib/ddnet/helpers';
import { browser } from '$app/environment';
import { tippy } from '$lib/tippy';
import { checkMapName, checkMapper } from '$lib/ddnet/searches';
let maps: MapList = $state([]);
let error = $state();
Expand Down Expand Up @@ -49,74 +50,11 @@
let paginatedMaps = $state<typeof maps>([]);
let totalPages = $state(1);
const checkMapName = (map: any, search: string) => {
if (!search) {
return true;
}
let mapInitial = '';
let mapNameNoSeparator = '';
let prevIsUpper = false;
let prevIsSeparator = true;
for (let i = 0; i < map.name.length; i++) {
const char = map.name[i];
const isUpper = char.match(/[A-Z]/);
const isLetter = isUpper || char.match(/[a-z]/);
const isSeparator = char == '-' || char == '_' || char == ' ';
const isNumber = char.match(/[0-9]/);
if (isUpper) {
if (!prevIsUpper || prevIsSeparator) {
mapInitial += char;
}
} else if (isLetter) {
if (prevIsSeparator) {
mapInitial += char;
}
} else if (isNumber) {
mapInitial += char;
}
prevIsUpper = isUpper;
prevIsSeparator = isSeparator;
if (!isSeparator) {
mapNameNoSeparator += char;
}
}
const mapName = map.name.toLowerCase();
const searchTextLower = search.toLowerCase();
return (
mapInitial.toLowerCase() == searchTextLower ||
mapNameNoSeparator.toLowerCase().includes(searchTextLower) ||
mapName.includes(searchTextLower)
);
};
const checkMapper = (map: any, search: string) => {
if (!search) {
return true;
}
const mapperString = map.mapper || '不详';
if (search.startsWith('"') && search.endsWith('"')) {
// exact match
const mappers = (mapperString as string)
.split(',')
.flatMap((mapper) => mapper.split('&'))
.map((mapper) => mapper.trim());
search = search.slice(1, -1).toLowerCase();
return mappers.some((mapper) => mapper.toLowerCase() == search);
}
return mapperString.toLowerCase().includes(search.toLowerCase());
};
$effect(() => {
if (!Array.isArray(maps)) return;
const filteredMaps = maps.filter((map: any) => {
return checkMapName(map, searchName) && checkMapper(map, searchMapper);
const filteredMaps = maps.filter((map: (typeof maps)[0]) => {
return checkMapName(map.name, searchName) && checkMapper(map.mapper, searchMapper);
});
totalPages = Math.ceil(filteredMaps.length / pageSize);
Expand Down
17 changes: 8 additions & 9 deletions src/routes/ddnet/players/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -123,18 +123,11 @@
]}
/>

<button
class="mb-2 cursor-pointer text-nowrap rounded bg-slate-700 px-4 py-2 font-semibold hover:bg-slate-600 active:bg-slate-700"
onclick={() => {
showModal = !showModal;
}}><Fa class="inline" icon={faQuestionCircle}></Fa> 了解分数计算方式</button
>

<div class="mb-4 space-y-2 md:flex md:space-x-5">
<div class="mb-4 flex-col space-y-2 md:flex md:flex-row md:space-x-2 md:space-y-0">
<input
type="text"
placeholder="查找玩家名"
class="w-full rounded border border-slate-600 bg-slate-700 p-2 text-slate-300 md:mb-0 md:flex-1"
class="w-full rounded border border-slate-600 bg-slate-700 px-4 py-2 text-slate-300 md:mb-0 md:flex-1"
bind:value={searchName}
onkeydown={(ev) => {
if (ev.key == 'Enter') {
Expand All @@ -149,6 +142,12 @@
>
查询玩家
</button>
<button
class="cursor-pointer text-nowrap rounded bg-slate-700 px-4 py-2 font-semibold hover:bg-slate-600 active:bg-slate-700"
onclick={() => {
showModal = !showModal;
}}><Fa class="inline" icon={faQuestionCircle}></Fa> 分数说明</button
>
</div>

<!-- horizontally scrollable list of cards -->
Expand Down
10 changes: 7 additions & 3 deletions src/routes/ddnet/players/[name]/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ interface MapData {
pending?: boolean;
};
};
pending_points?: number;
}

export const load = (async ({ fetch, parent, params, setHeaders }) => {
Expand Down Expand Up @@ -145,20 +144,25 @@ export const load = (async ({ fetch, parent, params, setHeaders }) => {
// don't count already finished maps
if (targetMap.first_finish) continue;

const mapFinishInfo = player.last_finishes.find((finish) => finish.map == map.name);
if (!mapFinishInfo) continue;

targetMap.finishes = 1;
targetMap.first_finish = mapFinishInfo.timestamp;
targetMap.pending = true;

// find the first finish time from the last finish list
const time = player.last_finishes.find((finish) => finish.map == map.name)?.time;
const time = mapFinishInfo.time;
targetMap.time = time ?? undefined;

const points = targetMap.points;

if (points) {
player.pending_points = (player.pending_points || 0) + points;
type.pending_points = (type.pending_points || 0) + points;
}

// if player has played more than 10 maps in the last 24 hours,
// we can't garantee the estimated points are accurate.
const lastFinish = player.last_finishes[player.last_finishes.length - 1];
if (lastFinish && Date.now() / 1000 - lastFinish.timestamp < 24 * 60 * 60) {
player.pending_unknown = true;
Expand Down
Loading

0 comments on commit 00977f4

Please sign in to comment.