-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.jsx
209 lines (181 loc) · 5.92 KB
/
server.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
import { renderToReadableStream } from "react-dom/server";
import CSS from "./App.css";
import { join } from "path";
import psList from "ps-list";
import pidCwd from "pid-cwd";
import Iron from "./assets/Tier/Iron.png";
import Bronze from "./assets/Tier/Bronze.png";
import Silver from "./assets/Tier/Silver.png";
import Gold from "./assets/Tier/Gold.png";
import Platinum from "./assets/Tier/Platinum.png";
import Emerald from "./assets/Tier/Emerald.png";
import Diamond from "./assets/Tier/Diamond.png";
import Master from "./assets/Tier/Master.png";
import Grandmaster from "./assets/Tier/Grandmaster.png";
import Challenger from "./assets/Tier/Challenger.png";
import Gray from "./assets/TFTTier/Gray.png";
import Green from "./assets/TFTTier/Green.png";
import Blue from "./assets/TFTTier/Blue.png";
import Purple from "./assets/TFTTier/Purple.png";
import Hyper from "./assets/TFTTier/Orange.png";
async function searchProcess(processes, targetName) {
const results = processes.filter((process) =>
process.name.includes(targetName)
);
return results.length > 0 ? results : null;
}
const Queue = {
RANKED_FLEX_SR: "Ranked Flex",
RANKED_SOLO_5x5: "Ranked Solo/Duo",
RANKED_TFT: "Ranked TFT",
RANKED_TFT_DOUBLE_UP: "Ranked TFT Double Up",
RANKED_TFT_PAIRS: "Ranked TFT (Double Up Beta)", // Deprecated ?
RANKED_TFT_TURBO: "Ranked TFT Hyper Roll",
};
function getKeyByValue(object, value) {
return Object.keys(object).find((key) => object[key] === value);
}
const mode = Queue.RANKED_FLEX_SR;
const mode_str = getKeyByValue(Queue, mode);
class LUC {
constructor() {
this.process_name = null;
this.process_id = null;
this.port = null;
this.password = null;
this.protocol = null;
this.last_pid = null;
}
async from_folder(path) {
const lockfile = Bun.file(join(path, "lockfile"));
if (await lockfile.exists()) {
const lockfile_content = (await lockfile.text()).split(":");
this.process_name = lockfile_content[0];
this.process_id = Number(lockfile_content[1]);
this.port = Number(lockfile_content[2]);
this.password = btoa("riot:" + lockfile_content[3]);
this.protocol = lockfile_content[4];
this.last_pid = process.pid;
return true;
}
return false;
}
async detect() {
const processes = await psList();
const targetProcessName = "LeagueClient";
const foundProcess = await searchProcess(processes, targetProcessName);
for (const process of foundProcess) {
// Nothing to do
if (process.pid == this.last_pid) return true;
}
for (const process of foundProcess) {
const cwd = await pidCwd(process.pid);
if (await this.from_folder(cwd)) return true;
}
// No process found
return false;
}
get_url(path) {
if (this.protocol && this.port && path)
return this.protocol + "://127.0.0.1:" + this.port + path;
else return null;
}
get_headers() {
if (this.password) return { Authorization: "Basic " + this.password };
else return null;
}
}
const luc = new LUC();
await luc.detect();
function title(string) {
return string.charAt(0).toUpperCase() + string.toLowerCase().slice(1);
}
var image = null;
var text1 = null;
var text2 = null;
async function updateRank() {
await luc.detect();
const response = await fetch(
luc.get_url("/lol-ranked/v1/current-ranked-stats"),
{
headers: luc.get_headers(),
}
);
const html = await response.json();
const stats = html["queueMap"][mode_str];
var tier = null;
if (mode === Queue.RANKED_TFT_TURBO) {
tier = title(stats["ratedTier"]);
const ratedRating = Number(stats["ratedRating"]);
text1 = `${tier} ${ratedRating} Points`;
text2 = null;
} else {
tier = title(stats["tier"]);
const rank = tier + " " + stats["division"];
const winsLosese = stats["wins"] + "W " + stats["losses"] + "L";
const lp = stats["leaguePoints"] + "LP";
const games = Number(stats["wins"]) + Number(stats["losses"]);
const winrate = (Number(stats["wins"]) / games) * 100;
const winratetext = winrate.toFixed(0) + "%";
text1 = `${rank} ${winsLosese}`;
text2 = `${lp} ${winratetext} Winrate`;
}
image = tier + ".png";
}
await updateRank();
setInterval(updateRank, 2000);
const jsc = `setTimeout(function(){
location.reload();
}, 2000);`;
const App = () => (
<html>
<head>
<title>Test</title>
<link rel="stylesheet" type="text/css" href="App.css" />
<script>{jsc}</script>
</head>
<body>
<div id="main">
<img src={image} alt="Logo" />
<div id="text">
<p>{text1}</p>
<p>{text2}</p>
</div>
</div>
</body>
</html>
);
const routes = {
"/Iron.png": Iron,
"/Bronze.png": Bronze,
"/Silver.png": Silver,
"/Gold.png": Gold,
"/Platinum.png": Platinum,
"/Emerald.png": Emerald,
"/Diamond.png": Diamond,
"/Master.png": Master,
"/Grandmaster.png": Grandmaster,
"/Challenger.png": Challenger,
"/App.css": CSS,
"/Gray.png": Gray,
"/Green.png": Green,
"/Blue.png": Blue,
"/Purple.png": Purple,
"/Hyper.png": Hyper,
};
const port = Number(process.env.PORT || 3001);
const headers = {
headers: {
"Content-Type": "text/html",
},
};
Bun.serve({
port,
async fetch(req) {
const path = new URL(req.url).pathname;
console.log(path);
if (path in routes) return new Response(Bun.file(routes[path]));
return new Response(await renderToReadableStream(<App />), headers);
},
});
console.log(`Server running on "http://localhost:${port}"`);