@sjtdev/koishi-plugin-dota2tracker 1.2.17 → 1.2.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +56 -30
- package/package.json +3 -3
- package/template/rank/temp.ejs +27 -0
- package/template/rank/rank2temp.html +0 -109
package/lib/index.js
CHANGED
|
@@ -50,13 +50,13 @@ __export(utils_exports, {
|
|
|
50
50
|
formatNumber: () => formatNumber,
|
|
51
51
|
getFormattedMatchData: () => getFormattedMatchData,
|
|
52
52
|
getImageUrl: () => getImageUrl,
|
|
53
|
+
init: () => init,
|
|
53
54
|
playerisValid: () => playerisValid,
|
|
54
55
|
query: () => query,
|
|
55
56
|
queryHeroFromValve: () => queryHeroFromValve,
|
|
56
57
|
readDirectoryFilesSync: () => readDirectoryFilesSync,
|
|
57
58
|
roundToDecimalPlaces: () => roundToDecimalPlaces,
|
|
58
59
|
sec2time: () => sec2time,
|
|
59
|
-
setHttp: () => setHttp,
|
|
60
60
|
winRateColor: () => winRateColor
|
|
61
61
|
});
|
|
62
62
|
var import_fs = __toESM(require("fs"));
|
|
@@ -70,10 +70,10 @@ __export(queries_exports, {
|
|
|
70
70
|
CURRENT_GAMEVERSION: () => CURRENT_GAMEVERSION,
|
|
71
71
|
HERO_INFO: () => HERO_INFO,
|
|
72
72
|
HERO_MATCHUP_WINRATE: () => HERO_MATCHUP_WINRATE,
|
|
73
|
-
MATCHES_FOR_DAILY: () => MATCHES_FOR_DAILY,
|
|
74
73
|
MATCH_INFO: () => MATCH_INFO,
|
|
75
74
|
PLAYERS_INFO_WITH_10_MATCHES_FOR_GUILD: () => PLAYERS_INFO_WITH_10_MATCHES_FOR_GUILD,
|
|
76
75
|
PLAYERS_LASTMATCH_RANKINFO: () => PLAYERS_LASTMATCH_RANKINFO,
|
|
76
|
+
PLAYERS_MATCHES_FOR_DAILY: () => PLAYERS_MATCHES_FOR_DAILY,
|
|
77
77
|
PLAYER_EXTRA_INFO: () => PLAYER_EXTRA_INFO,
|
|
78
78
|
PLAYER_INFO_WITH_25_MATCHES: () => PLAYER_INFO_WITH_25_MATCHES,
|
|
79
79
|
REQUEST_MATCH_DATA_ANALYSIS: () => REQUEST_MATCH_DATA_ANALYSIS,
|
|
@@ -221,10 +221,10 @@ function MATCH_INFO(matchId) {
|
|
|
221
221
|
`;
|
|
222
222
|
}
|
|
223
223
|
__name(MATCH_INFO, "MATCH_INFO");
|
|
224
|
-
function
|
|
224
|
+
function PLAYERS_MATCHES_FOR_DAILY(steamAccountIds, seconds) {
|
|
225
225
|
return `
|
|
226
226
|
{
|
|
227
|
-
players(steamAccountIds
|
|
227
|
+
players(steamAccountIds:[${steamAccountIds.join(",")}]) {
|
|
228
228
|
steamAccount{id name avatar}
|
|
229
229
|
matches(request:{startDateTime:${seconds} take:50}){
|
|
230
230
|
id
|
|
@@ -246,7 +246,7 @@ function MATCHES_FOR_DAILY(steamAccountIds, seconds) {
|
|
|
246
246
|
}
|
|
247
247
|
`;
|
|
248
248
|
}
|
|
249
|
-
__name(
|
|
249
|
+
__name(PLAYERS_MATCHES_FOR_DAILY, "PLAYERS_MATCHES_FOR_DAILY");
|
|
250
250
|
function VERIFYING_PLAYER(steamAccountId) {
|
|
251
251
|
return `
|
|
252
252
|
{
|
|
@@ -261,7 +261,7 @@ __name(VERIFYING_PLAYER, "VERIFYING_PLAYER");
|
|
|
261
261
|
function PLAYERS_LASTMATCH_RANKINFO(steamAccountIds) {
|
|
262
262
|
return `
|
|
263
263
|
{
|
|
264
|
-
players(steamAccountIds
|
|
264
|
+
players(steamAccountIds:[${steamAccountIds.join(",")}]) {
|
|
265
265
|
steamAccount{
|
|
266
266
|
id
|
|
267
267
|
name
|
|
@@ -530,11 +530,12 @@ __name(REQUEST_MATCH_DATA_ANALYSIS, "REQUEST_MATCH_DATA_ANALYSIS");
|
|
|
530
530
|
// src/utils.ts
|
|
531
531
|
var CONFIGS = { STRATZ_API: { URL: "https://api.stratz.com/graphql", TOKEN: "" } };
|
|
532
532
|
var http = null;
|
|
533
|
-
function
|
|
533
|
+
function init(newHttp, setTimeout2) {
|
|
534
534
|
http = newHttp;
|
|
535
|
+
setTimeout2 = setTimeout2;
|
|
535
536
|
}
|
|
536
|
-
__name(
|
|
537
|
-
async function
|
|
537
|
+
__name(init, "init");
|
|
538
|
+
async function fetchData(query_str) {
|
|
538
539
|
return await http.post(CONFIGS.STRATZ_API.URL, query_str, {
|
|
539
540
|
responseType: "json",
|
|
540
541
|
headers: {
|
|
@@ -544,6 +545,27 @@ async function query(query_str) {
|
|
|
544
545
|
}
|
|
545
546
|
});
|
|
546
547
|
}
|
|
548
|
+
__name(fetchData, "fetchData");
|
|
549
|
+
async function query(query_func, ...args) {
|
|
550
|
+
if (query_func.name.startsWith("PLAYERS") && args[0].length > 5) {
|
|
551
|
+
const playerIds = args[0];
|
|
552
|
+
const chunkSize = 5;
|
|
553
|
+
let allPlayers = [];
|
|
554
|
+
for (let i = 0; i < playerIds.length; i += chunkSize) {
|
|
555
|
+
const chunk = playerIds.slice(i, i + chunkSize);
|
|
556
|
+
const query_str = query_func(chunk, ...args.slice(1));
|
|
557
|
+
const result = await new Promise((resolve) => setTimeout(() => resolve(fetchData(query_str)), 100));
|
|
558
|
+
if (result.data && result.data.players) {
|
|
559
|
+
allPlayers = allPlayers.concat(result.data.players);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return { data: { players: allPlayers } };
|
|
563
|
+
} else {
|
|
564
|
+
const query_str = query_func(...args);
|
|
565
|
+
const result = await fetchData(query_str);
|
|
566
|
+
return result || {};
|
|
567
|
+
}
|
|
568
|
+
}
|
|
547
569
|
__name(query, "query");
|
|
548
570
|
async function queryHeroFromValve(heroId) {
|
|
549
571
|
return (await http.get(`https://www.dota2.com/datafeed/herodata?language=schinese&hero_id=${heroId}`)).result.data.heroes[0];
|
|
@@ -1252,7 +1274,7 @@ var Config = import_koishi.Schema.intersect([
|
|
|
1252
1274
|
import_koishi.Schema.object({
|
|
1253
1275
|
rankBroadSwitch: import_koishi.Schema.const(true).required(),
|
|
1254
1276
|
rankBroadStar: import_koishi.Schema.boolean().default(true).description("星级变动播报"),
|
|
1255
|
-
rankBroadLeader: import_koishi.Schema.boolean().default(true).description("
|
|
1277
|
+
rankBroadLeader: import_koishi.Schema.boolean().default(true).description("冠绝名次变动播报"),
|
|
1256
1278
|
rankBroadFun: import_koishi.Schema.boolean().default(false).description("整活播报模板")
|
|
1257
1279
|
}),
|
|
1258
1280
|
import_koishi.Schema.object({})
|
|
@@ -1292,7 +1314,7 @@ var pendingMatches = [];
|
|
|
1292
1314
|
var random = new import_koishi2.Random(() => Math.random());
|
|
1293
1315
|
async function apply(ctx, config) {
|
|
1294
1316
|
CONFIGS.STRATZ_API.TOKEN = config.STRATZ_API_TOKEN;
|
|
1295
|
-
|
|
1317
|
+
init(ctx.http, ctx.setTimeout);
|
|
1296
1318
|
ctx.command("订阅本群", "订阅后还需玩家在本群绑定SteamID").usage("订阅后还需玩家在本群绑定SteamID,BOT将订阅本群中已绑定玩家的新比赛数据,在STRATZ比赛解析完成后将比赛数据生成为图片战报发布至本群中。").action(async ({ session }) => {
|
|
1297
1319
|
if (session.guild) {
|
|
1298
1320
|
let currentGuild = (await ctx.database.get("dt_subscribed_guilds", { guildId: session.event.channel.id, platform: session.event.platform }))[0];
|
|
@@ -1388,15 +1410,19 @@ async function apply(ctx, config) {
|
|
|
1388
1410
|
}
|
|
1389
1411
|
if (subscribedPlayers.length <= 20) {
|
|
1390
1412
|
try {
|
|
1391
|
-
|
|
1413
|
+
let memberList;
|
|
1414
|
+
try {
|
|
1415
|
+
memberList = await session.bot?.getGuildMemberList(session.event.channel.id);
|
|
1416
|
+
} catch (error) {
|
|
1417
|
+
}
|
|
1392
1418
|
async function getUsers(subscribedPlayers2, utils, queries, memberList2) {
|
|
1393
1419
|
const playerSteamIds = subscribedPlayers2.map((player) => player.steamId);
|
|
1394
|
-
const queryResult = await utils.query(queries.PLAYERS_INFO_WITH_10_MATCHES_FOR_GUILD
|
|
1420
|
+
const queryResult = await utils.query(queries.PLAYERS_INFO_WITH_10_MATCHES_FOR_GUILD, playerSteamIds);
|
|
1395
1421
|
const playersInfo = queryResult.data.players;
|
|
1396
1422
|
const users2 = [];
|
|
1397
1423
|
for (const subscribedPlayer of subscribedPlayers2) {
|
|
1398
1424
|
const queryPlayer = playersInfo.find((player) => player.steamAccount.id == subscribedPlayer.steamId);
|
|
1399
|
-
const queryMember = memberList2
|
|
1425
|
+
const queryMember = memberList2?.data.find((member) => member.user?.id == subscribedPlayer.userId);
|
|
1400
1426
|
users2.push({ ...subscribedPlayer, ...queryPlayer, ...queryMember });
|
|
1401
1427
|
}
|
|
1402
1428
|
return users2;
|
|
@@ -1419,7 +1445,7 @@ async function apply(ctx, config) {
|
|
|
1419
1445
|
match = queryLocal[0].data;
|
|
1420
1446
|
ctx.database.set("dt_previous_query_results", match.id, { queryTime: /* @__PURE__ */ new Date() });
|
|
1421
1447
|
} else {
|
|
1422
|
-
match = getFormattedMatchData((await query(MATCH_INFO
|
|
1448
|
+
match = getFormattedMatchData((await query(MATCH_INFO, matchId)).data);
|
|
1423
1449
|
}
|
|
1424
1450
|
if (match && (match.parsedDateTime || import_moment.default.unix(match.endDateTime).isBefore((0, import_moment.default)().subtract(config.dataParsingTimeoutMinutes, "minutes")))) {
|
|
1425
1451
|
session.send((ctx.config.urlInMessageType.some((type) => type == "match") ? "https://stratz.com/matches/" + matchId : "") + await ctx.puppeteer.render(genImageHTML(match, config.template_match, "match" /* Match */)));
|
|
@@ -1441,7 +1467,6 @@ async function apply(ctx, config) {
|
|
|
1441
1467
|
session.send("请输入比赛ID。");
|
|
1442
1468
|
return;
|
|
1443
1469
|
}
|
|
1444
|
-
JSON.stringify;
|
|
1445
1470
|
if (!/^\d{10}$/.test(match_id)) {
|
|
1446
1471
|
session.send("比赛ID无效。");
|
|
1447
1472
|
return;
|
|
@@ -1467,9 +1492,10 @@ async function apply(ctx, config) {
|
|
|
1467
1492
|
let lastMatchId = 0;
|
|
1468
1493
|
try {
|
|
1469
1494
|
session.send("正在搜索对局详情,请稍后...");
|
|
1470
|
-
lastMatchId = (await query(PLAYERS_LASTMATCH_RANKINFO
|
|
1471
|
-
} catch {
|
|
1495
|
+
lastMatchId = (await query(PLAYERS_LASTMATCH_RANKINFO, [parseInt(flagBindedPlayer?.steamId ?? input_data)])).data.players[0].matches[0].id;
|
|
1496
|
+
} catch (error) {
|
|
1472
1497
|
session.send("获取玩家最近比赛失败。");
|
|
1498
|
+
ctx.logger.error(error);
|
|
1473
1499
|
return;
|
|
1474
1500
|
}
|
|
1475
1501
|
queryMatchAndSend(session, lastMatchId);
|
|
@@ -1497,8 +1523,8 @@ async function apply(ctx, config) {
|
|
|
1497
1523
|
let steamId = flagBindedPlayer?.steamId ?? input_data;
|
|
1498
1524
|
let player;
|
|
1499
1525
|
try {
|
|
1500
|
-
player = (await query(PLAYER_INFO_WITH_25_MATCHES
|
|
1501
|
-
let playerExtra = (await query(PLAYER_EXTRA_INFO
|
|
1526
|
+
player = (await query(PLAYER_INFO_WITH_25_MATCHES, steamId, hero?.id)).data.player;
|
|
1527
|
+
let playerExtra = (await query(PLAYER_EXTRA_INFO, steamId, player.matchCount, Object.keys(dotaconstants3.heroes).length, hero?.id)).data.player;
|
|
1502
1528
|
let filteredDotaPlus = {};
|
|
1503
1529
|
playerExtra.dotaPlus.forEach((item) => {
|
|
1504
1530
|
if (!filteredDotaPlus[item.heroId] || filteredDotaPlus[item.heroId].level < item.level) {
|
|
@@ -1646,7 +1672,7 @@ async function apply(ctx, config) {
|
|
|
1646
1672
|
return;
|
|
1647
1673
|
}
|
|
1648
1674
|
try {
|
|
1649
|
-
let heroStats = (await query(HERO_MATCHUP_WINRATE
|
|
1675
|
+
let heroStats = (await query(HERO_MATCHUP_WINRATE, hero.id)).data.heroStats;
|
|
1650
1676
|
let withTopFive = heroStats.matchUp[0].with.filter((item) => item.matchCount / heroStats.matchUp[0].matchCountWith > Math.max(0, Math.min(5, options.filter)) / 100).map((item) => {
|
|
1651
1677
|
const winRate = item.winCount / item.matchCount;
|
|
1652
1678
|
return { ...item, winRate: winRate.toFixed(3) };
|
|
@@ -1720,7 +1746,7 @@ async function apply(ctx, config) {
|
|
|
1720
1746
|
const subscribedPlayersSteamIds = subscribedPlayersInGuild.map((player) => player.steamId).filter(function(value, index, self) {
|
|
1721
1747
|
return self.indexOf(value) === index;
|
|
1722
1748
|
});
|
|
1723
|
-
const players = (await query(PLAYERS_LASTMATCH_RANKINFO
|
|
1749
|
+
const players = (await query(PLAYERS_LASTMATCH_RANKINFO, subscribedPlayersSteamIds)).data.players;
|
|
1724
1750
|
const lastMatches = players.map((player) => player.matches[0]).filter((item, index, self) => index === self.findIndex((t) => t.id === item.id)).filter((match) => import_moment.default.unix(match.startDateTime).isAfter((0, import_moment.default)().subtract(1, "days"))).filter((match) => !pendingMatches.some((pendingMatch) => pendingMatch.matchId == match.id));
|
|
1725
1751
|
const sendedMatchesIds = (await ctx.database.get("dt_sended_match_id", { matchId: lastMatches.map((match) => match.id) }, ["matchId"])).map((match) => match.matchId);
|
|
1726
1752
|
lastMatches.filter((match) => !sendedMatchesIds.includes(match.id)).forEach((match) => {
|
|
@@ -1735,7 +1761,7 @@ async function apply(ctx, config) {
|
|
|
1735
1761
|
});
|
|
1736
1762
|
});
|
|
1737
1763
|
pendingMatches.push({ matchId: match.id, guilds: tempGuilds });
|
|
1738
|
-
query(REQUEST_MATCH_DATA_ANALYSIS
|
|
1764
|
+
query(REQUEST_MATCH_DATA_ANALYSIS, match.id);
|
|
1739
1765
|
ctx.logger.info(
|
|
1740
1766
|
tempGuilds.map((guild) => `追踪到来自群组${guild.platform}:${guild.guildId}的用户${guild.players.map((player) => `[${player.nickName ?? ""}(${player.steamId})]`).join("、")}的尚未播报过的最新比赛 ${match.id}。`).join("")
|
|
1741
1767
|
);
|
|
@@ -1763,7 +1789,6 @@ async function apply(ctx, config) {
|
|
|
1763
1789
|
if (prevRank.medal !== currRank.medal || prevRank.star !== currRank.star && config.rankBroadStar || prevRank.leader !== currRank.leader && config.rankBroadLeader) {
|
|
1764
1790
|
const guildMember = await ctx.bots.find((bot) => bot.platform == subPlayer.platform)?.getGuildMember?.(subPlayer.guildId, subPlayer.userId);
|
|
1765
1791
|
const name2 = subPlayer.nickName ?? guildMember?.nick ?? players.find((player) => player.steamAccount.id == subPlayer.steamId)?.steamAccount.name ?? subPlayer.steamId;
|
|
1766
|
-
const message = `群友 ${name2} 段位变动:${rank[prevRank.medal]}${prevRank.star} → ${rank[currRank.medal]}${currRank.star} `;
|
|
1767
1792
|
if (config.rankBroadFun === true) {
|
|
1768
1793
|
const img = await ctx.puppeteer.render(
|
|
1769
1794
|
genImageHTML(
|
|
@@ -1780,10 +1805,11 @@ async function apply(ctx, config) {
|
|
|
1780
1805
|
);
|
|
1781
1806
|
await ctx.broadcast([`${subPlayer.platform}:${subPlayer.guildId}`], img);
|
|
1782
1807
|
} else {
|
|
1808
|
+
const message = `群友 ${name2} 段位变动:${rank[prevRank.medal]}${prevRank.star} → ${rank[currRank.medal]}${currRank.star} `;
|
|
1783
1809
|
const img = await ctx.puppeteer.render(genImageHTML(currRank, "rank" + (config.rankBroadFun ? "2" : ""), "rank" /* Rank */));
|
|
1784
1810
|
await ctx.broadcast([`${subPlayer.platform}:${subPlayer.guildId}`], message + img);
|
|
1785
1811
|
}
|
|
1786
|
-
ctx.logger.info(
|
|
1812
|
+
ctx.logger.info(`向 ${subPlayer.platform}:${subPlayer.guildId} 发布段位变动播报信息。`);
|
|
1787
1813
|
}
|
|
1788
1814
|
}
|
|
1789
1815
|
}
|
|
@@ -1800,7 +1826,7 @@ async function apply(ctx, config) {
|
|
|
1800
1826
|
if (queryLocal.length > 0) {
|
|
1801
1827
|
match = queryLocal[0].data;
|
|
1802
1828
|
ctx.database.set("dt_previous_query_results", match.id, { queryTime: /* @__PURE__ */ new Date() });
|
|
1803
|
-
} else match = getFormattedMatchData((await query(MATCH_INFO
|
|
1829
|
+
} else match = getFormattedMatchData((await query(MATCH_INFO, pendingMatch.matchId)).data);
|
|
1804
1830
|
if (match.parsedDateTime || import_moment.default.unix(match.endDateTime).isBefore(now.subtract(config.dataParsingTimeoutMinutes, "minutes"))) {
|
|
1805
1831
|
pendingMatches = pendingMatches.filter((item) => item.matchId != match.id);
|
|
1806
1832
|
const img = await ctx.puppeteer.render(genImageHTML(match, config.template_match, "match" /* Match */));
|
|
@@ -1842,10 +1868,9 @@ KDA:${((player.kills + player.assists) / (player.deaths || 1)).toFixed(2)} [${
|
|
|
1842
1868
|
const subscribedGuilds = await ctx.database.get("dt_subscribed_guilds", void 0);
|
|
1843
1869
|
const subscribedPlayersInGuild = (await ctx.database.get("dt_subscribed_players", void 0)).filter((player) => subscribedGuilds.some((guild) => guild.guildId == player.guildId));
|
|
1844
1870
|
const players = (await query(
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
)
|
|
1871
|
+
PLAYERS_MATCHES_FOR_DAILY,
|
|
1872
|
+
subscribedPlayersInGuild.map((player) => player.steamId).filter((value, index, self) => self.indexOf(value) === index),
|
|
1873
|
+
timeAgo
|
|
1849
1874
|
)).data.players.filter((player) => player.matches.length > 0);
|
|
1850
1875
|
const matches = players.map((player) => player.matches.map((match) => match)).flat().filter((item, index, self) => index === self.findIndex((t) => t.id === item.id));
|
|
1851
1876
|
for (let subPlayer of subscribedPlayersInGuild) {
|
|
@@ -1936,6 +1961,7 @@ function genImageHTML(data, template, type) {
|
|
|
1936
1961
|
dotaconstants: dotaconstants3,
|
|
1937
1962
|
moment: import_moment.default,
|
|
1938
1963
|
escapeHTML: /* @__PURE__ */ __name(function escapeHTML(str) {
|
|
1964
|
+
if (str == null) return "";
|
|
1939
1965
|
return str.replace(/[&<>"']/g, function(match) {
|
|
1940
1966
|
const escape = {
|
|
1941
1967
|
"&": "&",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjtdev/koishi-plugin-dota2tracker",
|
|
3
3
|
"description": "koishi插件-追踪群友的DOTA2对局",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.18",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
"dota2"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"dotaconstants": "^
|
|
29
|
+
"dotaconstants": "^9.3.0",
|
|
30
30
|
"ejs": "^3.1.10",
|
|
31
31
|
"moment": "^2.30.1"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"koishi": "^4.18.
|
|
34
|
+
"koishi": "^4.18.3"
|
|
35
35
|
},
|
|
36
36
|
"koishi": {
|
|
37
37
|
"preview": "true",
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>获取文件目录</title>
|
|
7
|
+
<script>
|
|
8
|
+
function showDirectory() {
|
|
9
|
+
// 获取当前页面的 URL
|
|
10
|
+
const url = window.location.href;
|
|
11
|
+
// 使用 URL 对象来解析当前 URL
|
|
12
|
+
const urlObj = new URL(url);
|
|
13
|
+
// 获取目录部分
|
|
14
|
+
const directory = urlObj.pathname.substring(0, urlObj.pathname.lastIndexOf('/'));
|
|
15
|
+
// 输出目录
|
|
16
|
+
document.getElementById('directory').innerText = directory;
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
console.log(directory)
|
|
20
|
+
}
|
|
21
|
+
</script>
|
|
22
|
+
</head>
|
|
23
|
+
<body onload="showDirectory()">
|
|
24
|
+
<h1>当前文件所在目录</h1>
|
|
25
|
+
<p id="directory"></p>
|
|
26
|
+
</body>
|
|
27
|
+
</html>
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Document</title>
|
|
7
|
-
<style>
|
|
8
|
-
* {
|
|
9
|
-
margin: 0;
|
|
10
|
-
padding: 0;
|
|
11
|
-
}
|
|
12
|
-
html {
|
|
13
|
-
width: 1024px;
|
|
14
|
-
height: 768px;
|
|
15
|
-
}
|
|
16
|
-
body.xi {
|
|
17
|
-
background: url(../images/xi.jpg) no-repeat center center / cover;
|
|
18
|
-
}
|
|
19
|
-
body.bei {
|
|
20
|
-
background: url(../images/bei.jpg) no-repeat center center / cover;
|
|
21
|
-
}
|
|
22
|
-
.wrapper {
|
|
23
|
-
padding: 80px;
|
|
24
|
-
padding-top: 180px;
|
|
25
|
-
}
|
|
26
|
-
.wrapper > p {
|
|
27
|
-
font-size: 32px;
|
|
28
|
-
line-height: 48px;
|
|
29
|
-
height: 48px;
|
|
30
|
-
text-align: center;
|
|
31
|
-
}
|
|
32
|
-
body.xi p.bei,
|
|
33
|
-
body.bei p.xi {
|
|
34
|
-
display: none;
|
|
35
|
-
}
|
|
36
|
-
.wrapper > p > span {
|
|
37
|
-
margin: 0 10px;
|
|
38
|
-
}
|
|
39
|
-
.wrapper > p > span.prev {
|
|
40
|
-
color: gray;
|
|
41
|
-
}
|
|
42
|
-
.wrapper > p > span.curr {
|
|
43
|
-
font-weight: bold;
|
|
44
|
-
color: red;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
.wrapper > p > img {
|
|
48
|
-
width: 48px;
|
|
49
|
-
height: 48px;
|
|
50
|
-
vertical-align: middle;
|
|
51
|
-
line-height: 48px;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
.ranks {
|
|
55
|
-
margin-top: 40px;
|
|
56
|
-
display: flex;
|
|
57
|
-
width: 100%;
|
|
58
|
-
height: 256px;
|
|
59
|
-
justify-content: space-evenly;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
div.rank {
|
|
63
|
-
position: relative;
|
|
64
|
-
width: 256px;
|
|
65
|
-
height: 256px;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
div.rank > img {
|
|
69
|
-
position: absolute;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
div.rank.prev {
|
|
73
|
-
filter: grayscale(1);
|
|
74
|
-
}
|
|
75
|
-
div.rank.curr {
|
|
76
|
-
transform: scale(1.25);
|
|
77
|
-
}
|
|
78
|
-
div.rank p {
|
|
79
|
-
font-size: 36px;
|
|
80
|
-
bottom: 20px;
|
|
81
|
-
width: 100%;
|
|
82
|
-
text-align: center;
|
|
83
|
-
color: #fff;
|
|
84
|
-
position: absolute;
|
|
85
|
-
}
|
|
86
|
-
</style>
|
|
87
|
-
</head>
|
|
88
|
-
<body class="bei">
|
|
89
|
-
<div class="wrapper">
|
|
90
|
-
<p class="xi">热烈祝贺群友 <img src="" alt="" />12414124141 在天梯中再获进步,</p>
|
|
91
|
-
<p class="xi">由<span class="rank prev">先锋2</span>升为<span class="rank curr">先锋2</span>,再接再厉,再创辉煌!</p>
|
|
92
|
-
<p class="bei"><img src="" alt="" /></p>
|
|
93
|
-
<p class="bei">寄</p>
|
|
94
|
-
<div class="ranks">
|
|
95
|
-
<div class="rank prev">
|
|
96
|
-
<img src="../images/medal_8.png" alt="" />
|
|
97
|
-
<img src="../images/star_2.png" alt="" />
|
|
98
|
-
<p>1111</p>
|
|
99
|
-
</div>
|
|
100
|
-
<div class="rank curr">
|
|
101
|
-
<img src="../images/medal_8.png" alt="" />
|
|
102
|
-
<img src="../images/star_1.png" alt="" />
|
|
103
|
-
<p>1111</p>
|
|
104
|
-
</div>
|
|
105
|
-
</div>
|
|
106
|
-
<p style="text-align: right; margin-top: 40px;">—— 2024/11/11 00点00分</p>
|
|
107
|
-
</div>
|
|
108
|
-
</body>
|
|
109
|
-
</html>
|