Merge branch 'main' into work/prop
This commit is contained in:
commit
46d471b43b
48
.github/workflows/static.yml
vendored
Normal file
48
.github/workflows/static.yml
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
# Simple workflow for deploying static content to GitHub Pages
|
||||
name: GitHub pages 部署
|
||||
|
||||
on:
|
||||
# Runs on pushes targeting the default branch
|
||||
push:
|
||||
branches: ["main"]
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
|
||||
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
# Single deploy job since we're just deploying
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: 运行部署脚本
|
||||
run: python3 deploy.py
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v5
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
# Upload entire repository
|
||||
path: '.'
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
@ -140,7 +140,7 @@
|
||||
"HP": "HP",
|
||||
"detail": " 攻 [] 防 [] 速 [] 敏 [] 魔 [] 抗 [] 智 []",
|
||||
"inputTitle": "名字竞技场",
|
||||
"inputPlaceholder": "每行输入一个名字\n\n组队对战时用空行隔开组队\n\n修改by shenjackyuanjie",
|
||||
"inputPlaceholder": "每行输入一个名字\n\n组队对战时用空行隔开组队\n\n修改by shenjackyuanjie&超导体元素",
|
||||
"startFight": "开 始",
|
||||
"closeTitle": "关闭",
|
||||
"fastTitle": "快进",
|
||||
|
@ -560,13 +560,23 @@
|
||||
0%,
|
||||
80%,
|
||||
100% {
|
||||
transform: scale(0);
|
||||
transform: scale(0)
|
||||
}
|
||||
|
||||
40% {
|
||||
transform: scale(1);
|
||||
transform: scale(1)
|
||||
}
|
||||
}
|
||||
|
||||
#version-marker {
|
||||
background-color: white;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
border-radius: 5px;
|
||||
/* border: 2px solid marker_color */
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
<style id="pstyle">
|
||||
</style>
|
||||
@ -618,6 +628,8 @@
|
||||
<body>
|
||||
<div id="done_target" class="done_target" style="display: none;"></div>
|
||||
<!-- 用于标记是否完事 默认隐藏-->
|
||||
<div id="version-marker" style="display: none;"></div>
|
||||
<!-- 左上角一个用于标记版本号的 div, 默认状况下不显示, 部署时使用脚本替换内容, 颜色同理 -->
|
||||
<img src="thumb.jpg" width="0" height="0" />
|
||||
<div class='ad_h'></div>
|
||||
<div class='ad_v'></div>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -708,6 +708,7 @@
|
||||
window.localStorage.setItem(s, new H.c3(H.setRuntimeTypeInfo($.i7.d.split(""), t.s), t.H).cZ(0))
|
||||
}
|
||||
// $.ht = J.iH($.id.d, "[1,3,0,9]", J.aD($.hA))
|
||||
// MARK: 替换 md5.js
|
||||
$.ht = J.iH($.id.d, "[1, 3, 0, 9]", J.aD($.hA))
|
||||
r = (self.URL || self.webkitURL).createObjectURL(W.iK([$.i8.d], "text/css"))
|
||||
q = (self.URL || self.webkitURL).createObjectURL(W.iK([J.iH($.ib.d, "md5.css", r)], "text/html"))
|
||||
@ -7021,6 +7022,7 @@
|
||||
aN(a, b) {
|
||||
var s
|
||||
if (b == null) b = P.hH(a)
|
||||
console.error(a, b)
|
||||
s = this.a
|
||||
if (this.b) s.af(a, b)
|
||||
else s.b4(a, b)
|
||||
|
@ -567,6 +567,16 @@
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
#version-marker {
|
||||
background-color: white;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
border-radius: 5px;
|
||||
/* border: 2px solid marker_color */
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
<style id="pstyle">
|
||||
</style>
|
||||
@ -618,6 +628,8 @@
|
||||
<body>
|
||||
<div id="done_target" class="done_target" style="display: none;"></div>
|
||||
<!-- 用于标记是否完事 默认隐藏-->
|
||||
<div id="version-marker" style="display: none;"></div>
|
||||
<!-- 左上角一个用于标记版本号的 div, 默认状况下不显示, 部署时使用脚本替换内容, 颜色同理 -->
|
||||
<img src="thumb.jpg" width="0" height="0" />
|
||||
<div class='ad_h'></div>
|
||||
<div class='ad_v'></div>
|
||||
|
205
branch/latest/md5-api.ts
Normal file
205
branch/latest/md5-api.ts
Normal file
@ -0,0 +1,205 @@
|
||||
const md5_module = require("./md5.js");
|
||||
|
||||
/**
|
||||
* 对战结果的数据结构
|
||||
* 其实只有 source_plr 是有用的, 是赢家之一
|
||||
*/
|
||||
type FightResult = {
|
||||
message: string;
|
||||
source_plr: string;
|
||||
target_plr: string;
|
||||
affect: string | number;
|
||||
};
|
||||
|
||||
/**
|
||||
* 每一行具体的胜率结果
|
||||
*/
|
||||
type WinRate = {
|
||||
round: number;
|
||||
win_count: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* 胜率的数据结构
|
||||
*/
|
||||
type WinRateResult = {
|
||||
win_count: number;
|
||||
raw_data: WinRate[];
|
||||
};
|
||||
|
||||
/**
|
||||
* 用于接收胜率的回调函数
|
||||
* 返回一个 bool, true 表示继续, false 表示停止
|
||||
*/
|
||||
type WinRateCallback = (run_round: number, win_count: number) => boolean;
|
||||
|
||||
/**
|
||||
* 分数的数据结构
|
||||
*/
|
||||
type Score = {
|
||||
round: number;
|
||||
score: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* 分数的数据结构
|
||||
*/
|
||||
type ScoreResult = {
|
||||
score: number;
|
||||
raw_data: Score[];
|
||||
};
|
||||
|
||||
/**
|
||||
* 用于接收分数的回调函数
|
||||
* 返回一个 bool, true 表示继续, false 表示停止
|
||||
*/
|
||||
type ScoreCallback = (run_round: number, score: number) => boolean;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param names 原始的输入框输入
|
||||
* @returns 对战结果
|
||||
*/
|
||||
async function fight(names: string): Promise<FightResult> {
|
||||
// 检查一下输入是否合法
|
||||
// 比如里面有没有 !test!
|
||||
if (names.indexOf("!test!") !== -1) {
|
||||
throw new Error("你怎么在对战输入里加 !test!(恼)\n${names}");
|
||||
}
|
||||
return await md5_module.fight(names);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对于胜率/评分的输入检查
|
||||
* @param names
|
||||
* @returns
|
||||
*/
|
||||
function test_check(names: string): boolean {
|
||||
const have_test = names.trim().startsWith("!test!");
|
||||
|
||||
return have_test;
|
||||
}
|
||||
|
||||
/**
|
||||
* 测量胜率
|
||||
* @param names 原始的输入框输入
|
||||
* @param round 战斗的回合数
|
||||
* @returns 胜率结果
|
||||
*/
|
||||
async function win_rate(names: string, round: number): Promise<WinRateResult> {
|
||||
// 检查 round 是否合法
|
||||
if (round <= 0) {
|
||||
throw new Error("round 必须大于 0");
|
||||
}
|
||||
if (!test_check(names)) {
|
||||
throw new Error("你怎么在胜率输入里丢了 !test!(恼)\n${names}");
|
||||
}
|
||||
return await md5_module.win_rate(names, round);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param names 原始的输入框输入
|
||||
* @param callback 用于接收胜率的回调函数
|
||||
* @returns 胜率结果
|
||||
*/
|
||||
async function win_rate_callback(
|
||||
names: string,
|
||||
callback: WinRateCallback,
|
||||
): Promise<WinRateResult> {
|
||||
if (!test_check(names)) {
|
||||
throw new Error("你怎么在胜率输入里丢了 !test!(恼)\n${names}");
|
||||
}
|
||||
return await md5_module.win_rate_callback(names, callback);
|
||||
}
|
||||
|
||||
async function score(names: string, round: number): Promise<ScoreResult> {
|
||||
// 检查 round 是否合法
|
||||
if (round <= 0) {
|
||||
throw new Error("round 必须大于 0");
|
||||
}
|
||||
if (!test_check(names)) {
|
||||
throw new Error("你怎么在分数输入里丢了 !test!(恼)\n${names}");
|
||||
}
|
||||
return await md5_module.score(names, round);
|
||||
}
|
||||
|
||||
async function score_callback(
|
||||
names: string,
|
||||
callback: ScoreCallback,
|
||||
): Promise<ScoreResult> {
|
||||
if (!test_check(names)) {
|
||||
throw new Error("你怎么在分数输入里加 !test!(恼)\n${names}");
|
||||
}
|
||||
return await md5_module.score_callback(names, callback);
|
||||
}
|
||||
|
||||
async function run_any(names: string, round: number): Promise<FightResult | WinRateResult | ScoreResult> {
|
||||
return await md5_module.run_any(names, round);
|
||||
}
|
||||
|
||||
const out_limit: number = 1000;
|
||||
|
||||
async function wrap_any(names: string, round: number): Promise<string> {
|
||||
const result = await run_any(names, round);
|
||||
if ('message' in result) {
|
||||
// 对战结果
|
||||
return `赢家:|${result.source_plr}|`;
|
||||
} else if ('win_count' in result) {
|
||||
// 胜率结果
|
||||
const win_rate = result.win_count * 100 / round;
|
||||
let win_rate_str = win_rate.toFixed(4);
|
||||
let output_str = `最终胜率:|${win_rate_str}%|(${round}轮)`;
|
||||
// 每 500 轮, 输出一次
|
||||
if (round > out_limit) {
|
||||
// 把所有要找的数据拿出来
|
||||
let output_datas: WinRate[] = [];
|
||||
result.raw_data.forEach((data, index) => {
|
||||
if (data.round % out_limit === 0) {
|
||||
output_datas.push(data);
|
||||
}
|
||||
});
|
||||
output_datas.forEach((data, index) => {
|
||||
const win_rate = data.win_count * 100 / data.round;
|
||||
output_str += `\n${win_rate.toFixed(2)}%(${data.round})`;
|
||||
});
|
||||
}
|
||||
return output_str;
|
||||
// } else if ('score' in result) {
|
||||
} else {
|
||||
// 分数结果其实还是个胜率, 不过需要 * 100
|
||||
const win_rate = (result.score * 10000 / round).toFixed(2);
|
||||
let output_str = `分数:|${win_rate}|(${round}轮)`;
|
||||
if (round > out_limit) {
|
||||
// 把所有要找的数据拿出来
|
||||
let output_datas: Score[] = [];
|
||||
result.raw_data.forEach((data, index) => {
|
||||
if (data.round % out_limit === 0) {
|
||||
output_datas.push(data);
|
||||
}
|
||||
});
|
||||
output_datas.forEach((data, index) => {
|
||||
const win_rate = (data.score / data.round * 10000).toFixed(2);
|
||||
output_str += `\n${win_rate}(${data.round})`;
|
||||
});
|
||||
}
|
||||
return output_str;
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
FightResult,
|
||||
WinRate,
|
||||
WinRateResult,
|
||||
WinRateCallback,
|
||||
Score,
|
||||
ScoreResult,
|
||||
ScoreCallback,
|
||||
fight,
|
||||
win_rate,
|
||||
win_rate_callback,
|
||||
score,
|
||||
score_callback,
|
||||
run_any,
|
||||
wrap_any,
|
||||
};
|
19042
branch/latest/md5.js
19042
branch/latest/md5.js
File diff suppressed because it is too large
Load Diff
94
branch/latest/test.ts
Normal file
94
branch/latest/test.ts
Normal file
@ -0,0 +1,94 @@
|
||||
// 请使用 bun 运行
|
||||
|
||||
import { fight, score, win_rate } from "./md5-api";
|
||||
|
||||
const test_profiles = {
|
||||
fight: [
|
||||
{
|
||||
test: `vy5we
|
||||
w\n ryyb\nb\nrv\nv\netet4y 54 w\ne rg\nwe by\nrw \nte\nw \nnbyrb\n ew\nyn re\nryb\ney w\nneb r\nbwe\nn yrbq34nb\net\nab\nqbetq\n45ywy54\ny45\n45\nwv54\nyw\nvy\n5y\nvyev\nyeevy\nvey\ne\nrye\nyn\n43n\n63\nub63 u\nb6r\nun\n3br\nue\nrnbt\n4n\n5b\nwu\n4bw\n4nw\n4u \nn6w\nr`, winner: "rye"
|
||||
},
|
||||
{
|
||||
test: 'm@fAIgFUL\n1 1 @Ehlt s',
|
||||
winner: "m@fAIgFUL"
|
||||
},
|
||||
],
|
||||
win_chance: [
|
||||
{
|
||||
test: `
|
||||
!test!
|
||||
|
||||
http://shenjack.top:81/md5/branch/latest/
|
||||
|
||||
http://shenjack.top:81/md5`,
|
||||
round_10: 0.513,
|
||||
round_100: 0.5106,
|
||||
},
|
||||
],
|
||||
score: [
|
||||
{
|
||||
test: `
|
||||
!test!
|
||||
|
||||
http://shenjack.top:81/md5/branch/latest/`,
|
||||
round_10: 1480,
|
||||
round_100: 1903, // todo
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
async function test() {
|
||||
for (const profile of test_profiles.fight) {
|
||||
const result = await fight(profile.test);
|
||||
if (result.source_plr === profile.winner) {
|
||||
console.log("pass");
|
||||
} else {
|
||||
throw new Error("fail" + result.source_plr + " " + profile.winner + " " + profile.test);
|
||||
}
|
||||
}
|
||||
for (const profile of test_profiles.win_chance) {
|
||||
console.log(profile.test);
|
||||
const result = await win_rate(profile.test, 100 * 100);
|
||||
// 分别校验 10 * 100 和 100 * 100 轮的胜率
|
||||
for (const data of result.raw_data) {
|
||||
if (data.round === 10 * 100) {
|
||||
const rate = data.win_count / data.round;
|
||||
if (rate === profile.round_10) {
|
||||
console.log("pass");
|
||||
} else {
|
||||
throw new Error("fail" + rate + " " + profile.round_10);
|
||||
}
|
||||
} else if (data.round === 100 * 100) {
|
||||
const rate = data.win_count / data.round;
|
||||
if (rate === profile.round_100) {
|
||||
console.log("pass");
|
||||
} else {
|
||||
throw new Error("fail" + rate + " " + profile.round_100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for (const profile of test_profiles.score) {
|
||||
console.log(profile.test);
|
||||
const result = await score(profile.test, 100 * 100);
|
||||
for (const data of result.raw_data) {
|
||||
if (data.round === 10 * 100) {
|
||||
if (data.score * 10 === profile.round_10) {
|
||||
console.log("pass");
|
||||
} else {
|
||||
throw new Error("fail" + data.score + " " + profile.round_10);
|
||||
}
|
||||
} else if (data.round === 100 * 100) {
|
||||
if (data.score === profile.round_100) {
|
||||
console.log("pass");
|
||||
} else {
|
||||
throw new Error("fail" + data.score + " " + profile.round_100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
test();
|
127
deploy.py
127
deploy.py
@ -1 +1,128 @@
|
||||
<<<<<<< HEAD
|
||||
# 只是一个 dummy file
|
||||
=======
|
||||
import os
|
||||
import random
|
||||
|
||||
from subprocess import run
|
||||
from pathlib import Path
|
||||
|
||||
ON_CF = os.getenv("CF_PAGES") == "1"
|
||||
|
||||
if ON_CF:
|
||||
print("Running on Cloudflare Pages, trying to git fetch --all")
|
||||
result = run(["git", "fetch", "--all"], check=False)
|
||||
print(f"git fetch --all: {result}")
|
||||
# 提前尝试输出一遍下面这堆信息
|
||||
run(["git", "branch", "--show-current"], check=False)
|
||||
run(["git", "rev-parse", "HEAD"], check=False)
|
||||
run(["git", "describe", "--tags"], check=False)
|
||||
run(["git", "log", "-1", "--pretty=%B"], check=False)
|
||||
|
||||
|
||||
def get_env_info() -> dict[str, str]:
|
||||
# 读取环境变量
|
||||
env_info = {}
|
||||
# git branch
|
||||
if ON_CF:
|
||||
branch = os.getenv("CF_PAGES_BRANCH") or "unknown"
|
||||
else:
|
||||
branch = run(
|
||||
["git", "branch", "--show-current"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
).stdout
|
||||
env_info["branch"] = branch.strip()
|
||||
# git commit hash
|
||||
if ON_CF:
|
||||
commit = os.getenv("CF_PAGES_COMMIT_SHA") or "unknown"
|
||||
else:
|
||||
commit = run(
|
||||
["git", "rev-parse", "HEAD"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
).stdout
|
||||
env_info["commit"] = commit.strip()
|
||||
# git commit message
|
||||
message = run(
|
||||
["git", "log", "-1", "--pretty=%B"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
)
|
||||
env_info["message"] = message.stdout.strip()
|
||||
# git tag
|
||||
if ON_CF:
|
||||
tag = run(
|
||||
["git", "describe", "--tags"], capture_output=True, text=True, encoding="utf-8"
|
||||
).stdout.split("-")[0] or "cf_pages"
|
||||
else:
|
||||
tag = run(
|
||||
["git", "describe", "--tags"], capture_output=True, text=True, encoding="utf-8"
|
||||
).stdout.split("-")[0]
|
||||
env_info["tag"] = tag.strip()
|
||||
return env_info
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 虽然但是, 我还是决定用 python 写这个脚本
|
||||
|
||||
border_raw = "/* border: 2px solid marker_color */"
|
||||
border_template = "border: 2px solid {};"
|
||||
marker_raw = '<div id="version-marker" style="display: none;"></div>'
|
||||
marker_template = '<div id="version-marker">{}</div>'
|
||||
|
||||
# 读取环境变量
|
||||
env_info = get_env_info()
|
||||
tag = env_info["tag"]
|
||||
branch = env_info["branch"]
|
||||
commit = env_info["commit"]
|
||||
message = env_info["message"]
|
||||
|
||||
for file in Path.cwd().rglob("index.html"):
|
||||
try:
|
||||
with open(file, "r", encoding="utf-8") as f:
|
||||
raw_content = f.read()
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
continue
|
||||
print(f"Reading: {file}")
|
||||
|
||||
# 替换内容
|
||||
# 首先判断是否是 /branch 目录下的 index.html
|
||||
if "branch" in str(file):
|
||||
# 如果是, 则将颜色替换为 random(这里是为了区分不同的分支, 并且颜色相对固定)
|
||||
file_branch_name = file.parent.name
|
||||
randomer = random.Random(file_branch_name)
|
||||
hash_color = randomer.randint(0, 0xFFFFFF)
|
||||
border = border_template.format(f"#{hash_color:06x}")
|
||||
|
||||
# git 信息:
|
||||
version_info = f"{file_branch_name}/{branch}:{tag}-{commit[:6]}<br/>{message}"
|
||||
marker = marker_template.format(version_info)
|
||||
|
||||
print(f"Branch: {file_branch_name}\n{border}\n{marker}\n")
|
||||
|
||||
else:
|
||||
# 淡绿色!
|
||||
border = border_template.format("greenyellow")
|
||||
|
||||
# git 信息:
|
||||
version_info = f"{branch}:{tag}-{commit[:6]}"
|
||||
marker = marker_template.format(version_info)
|
||||
print(f"Master: {border}\n{marker}\n")
|
||||
|
||||
raw_content = raw_content.replace(border_raw, border).replace(
|
||||
marker_raw, marker
|
||||
)
|
||||
|
||||
# 写入文件
|
||||
try:
|
||||
with open(file, "w", encoding="utf-8") as f:
|
||||
f.write(raw_content)
|
||||
except Exception as e:
|
||||
print(f"Error writing file: {e}")
|
||||
continue
|
||||
>>>>>>> main
|
||||
|
12
index.html
12
index.html
@ -569,6 +569,16 @@
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
#version-marker {
|
||||
background-color: white;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
border-radius: 5px;
|
||||
/* border: 2px solid marker_color */
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
<style id="pstyle">
|
||||
</style>
|
||||
@ -620,6 +630,8 @@
|
||||
<body>
|
||||
<div id="done_target" class="done_target" style="display: none;"></div>
|
||||
<!-- 用于标记是否完事 默认隐藏-->
|
||||
<div id="version-marker" style="display: none;"></div>
|
||||
<!-- 左上角一个用于标记版本号的 div, 默认状况下不显示, 部署时使用脚本替换内容, 颜色同理 -->
|
||||
<img src="thumb.jpg" width="0" height="0" />
|
||||
<div class='ad_h'></div>
|
||||
<div class='ad_v'></div>
|
||||
|
@ -77,3 +77,12 @@ wu
|
||||
n6w
|
||||
r
|
||||
```
|
||||
|
||||
## 2.seed 测试
|
||||
|
||||
```plaintext
|
||||
adawada
|
||||
aeagfsdf
|
||||
|
||||
seed:seed@!
|
||||
```
|
||||
|
Loading…
Reference in New Issue
Block a user