Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/bot discord #5

Open
wants to merge 35 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
19265e6
refactorig
Feb 5, 2022
5bb5794
fix: store
Feb 5, 2022
36e41e6
feat: center friendlist page
Feb 5, 2022
e896701
feat: store
Feb 6, 2022
38d2727
fix: notifications
Feb 6, 2022
ba81df5
feat: create db on runtime
Feb 6, 2022
c11f484
feat: store db in userData folder
Feb 6, 2022
417f8b5
feat: send all notifications info update
Feb 6, 2022
63eb9f0
minor fixes
Feb 8, 2022
d957c7a
feat: send apex to ws backend
Feb 8, 2022
4c5fb00
feat: new url
Feb 9, 2022
9987353
feat: remove in lobby from friend activity
Feb 9, 2022
677d317
feat: focus window on discord callback
Feb 9, 2022
0f10adb
feat: game status
Feb 9, 2022
edf50f6
feat: send all notification infos to ws
Feb 9, 2022
a0b9fce
feat: disable empty cache
Feb 10, 2022
7c7966e
fix: layout
Feb 10, 2022
3fcf54a
feat: remove all stalked summoners from discord guild
Feb 10, 2022
c891b7e
feat: use ws instead of websockets + icon
Feb 10, 2022
5e51fbb
feat: new icon
Feb 10, 2022
08ba6b7
fix: build
Feb 10, 2022
1d189fa
refactor: split Discord.tsx into multiple files
Feb 10, 2022
92020e6
feat: server restriction + current summoner elo graph
Feb 11, 2022
d282780
feat: set version to 0.1.0
Feb 11, 2022
8cb2e40
fix: get db url
Feb 11, 2022
0a7e38b
feat: ws reconnect loop
Feb 13, 2022
b576574
feat: add/remove summoners using api + friendlist search bar
Feb 14, 2022
d4e1734
feat: add promo notifications
Feb 14, 2022
19ba3ca
fix: update apex every 15 minutes
Feb 14, 2022
e58a51b
feat: add message button if 99 LPs
Feb 14, 2022
75ef78d
fix: remove spectating from in game friends
Feb 14, 2022
0e0753d
feat: miniseriesprogress
Feb 14, 2022
fbeb351
feat: is in friendlist + fix api
Feb 16, 2022
e7fc0b4
fix
Feb 16, 2022
f0be75a
wip
Feb 18, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions .env
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
PORT = 3002
HTTPS = TRUE

TYPEORM_CONNECTION = sqlite
TYPEORM_HOST = localhost
TYPEORM_USERNAME = root
TYPEORM_PASSWORD = admin
TYPEORM_DATABASE = database/lol-stalker.db
TYPEORM_PORT = 3000
TYPEORM_SYNCHRONIZE = false
TYPEORM_ENTITIES = **/entities/*.js
TYPEORM_MIGRATIONS_DIR = migration
TYPEORM_MIGRATIONS = migration/*.js
#TYPEORM_CONNECTION = sqlite
#TYPEORM_HOST = localhost
#TYPEORM_USERNAME = root
#TYPEORM_PASSWORD = admin
#TYPEORM_DATABASE = $Env:APPDATA/LoL-stalker/database/lol-stalker.dev.db
#TYPEORM_PORT = 3000
#TYPEORM_SYNCHRONIZE = false
#TYPEORM_ENTITIES = **/entities/*.js
#TYPEORM_MIGRATIONS_DIR = electron/migration
#TYPEORM_MIGRATIONS = migration/*.js

TYPEORM_LOGGING = false
#TYPEORM_LOGGING = false
35 changes: 0 additions & 35 deletions electron/config.ts

This file was deleted.

40 changes: 30 additions & 10 deletions electron/db.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,36 @@
import isDev from "electron-is-dev";
import path from "path";
import fs from "fs/promises";
import sqlite3 from "sqlite3";

import { createConnection } from "typeorm";
const dbUrl = path.join(__dirname, "database", "lol-stalker.db");
// export const db = new sqlite3.Database(dbUrl);
import { app } from "electron";
const dbFolder = path.join(app.getPath("userData"), "database");
const dbUrl = path.join(dbFolder, isDev ? "lol-stalker.dev.db" : "lol-stalker.db");

export const makeDb = () =>
isDev
? createConnection()
: createConnection({
type: "sqlite",
database: dbUrl,
entities: [path.join(__dirname, "entities/*")],
});
export const makeDb = async () => {
try {
await fs.stat(dbFolder);
} catch (e) {
await fs.mkdir(dbFolder);
}
try {
await fs.stat(dbUrl);
} catch (e) {
await createDbFile();
console.log(`db file ${dbUrl} does not exist, creating it`);
}

return createConnection({
type: "sqlite",
database: dbUrl,
entities: [path.join(__dirname, "entities/*")],
migrationsRun: true,
migrations: [path.join(__dirname, "migration/*")],
});
};

const createDbFile = () =>
new Promise((resolve, reject) => {
new sqlite3.Database(dbUrl, (err) => (err ? reject(err) : resolve(true)));
});
3 changes: 3 additions & 0 deletions electron/entities/Friend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ export class Friend {
@Column("datetime", { name: "createdAt", default: () => "CURRENT_TIMESTAMP" })
createdAt: Date;

@Column("text", { name: "subscription", nullable: true })
subscription: string;

@Column("boolean", { name: "isCurrentSummoner", default: () => "false" })
isCurrentSummoner: boolean;

Expand Down
39 changes: 39 additions & 0 deletions electron/features/autoLaunch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import AutoLaunch from "auto-launch";
import electronIsDev from "electron-is-dev";
import { editStoreEntry, store } from "./store";

export const initAutoLauch = async () => {
const autoLaunch = new AutoLaunch({ name: "LoL Stalker" });
await editStoreEntry("autoLaunch", autoLaunch);

if (electronIsDev) return console.log("AutoLaunch doesn't work in development");
const isEnabled = await autoLaunch.isEnabled();

if (store.config.autoLaunch && !isEnabled) autoLaunch.enable();
else if (isEnabled) autoLaunch.disable();
};

export const enableAutoLaunch = async () => {
console.log("enabling autolaunch...");
if (electronIsDev) return console.log("AutoLaunch doesn't work in development");
const autoLaunch = store.autoLaunch;
if (!autoLaunch) return;

const isEnabled = await autoLaunch.isEnabled();

if (isEnabled) return;
autoLaunch.enable();
console.log("autolaunch enabled");
};

export const disableAutoLauch = async () => {
console.log("disabling autolaunch...");
const autoLaunch = store.autoLaunch;
if (!autoLaunch) return;

const isEnabled = await autoLaunch.isEnabled();

if (!isEnabled) return;
autoLaunch.disable();
console.log("autolaunch disabled");
};
39 changes: 21 additions & 18 deletions electron/LCU/lcu.ts → electron/features/lcu/lcu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,37 @@ import { pick } from "@pastable/core";
import axios, { AxiosInstance } from "axios";
import https from "https";
import LCUConnector from "lcu-connector";
import { Friend } from "../entities/Friend";
import { sendInvalidate } from "../routes";
import { addOrUpdateFriends, getSelectedFriends } from "../routes/friends";
import { selectedFriends } from "../selection";
import { sendToClient, Tier } from "../utils";
import { Friend } from "../../entities/Friend";
import { sendToClient, Tier } from "../../utils";
import { CurrentSummoner, FriendDto, MatchDto, Queue, RankedStats } from "./types";
import { editStoreEntry, Locale, store } from "../store";
import { addOrUpdateFriends } from "../routes/friends";

const httpsAgent = new https.Agent({ rejectUnauthorized: false });
export const connector = new LCUConnector();
export const connectorStatus = {
current: null as any,
api: null as unknown as AxiosInstance,
};

export const sendConnectorStatus = () => sendToClient("lcu/connection", connectorStatus.current);
export const sendConnectorStatus = () => sendToClient("lcu/connection", store.connectorStatus);

connector.on("connect", async (data) => {
connectorStatus.current = data;
editStoreEntry("connectorStatus", data);
const { protocol, username, password, address, port } = data;
const baseURL = `${protocol}://${username}:${password}@${address}:${port}`;
connectorStatus.api = axios.create({
store.lcu = axios.create({
baseURL,
httpsAgent,
headers: { Authorization: `Basic ${data.password}` },
});
console.log("connected to riot client");

try {
const locale = await getRegionLocale();
await editStoreEntry("locale", locale);
} catch (e) {
console.log(e);
}
});
connector.on("disconnect", () => {
connectorStatus.current = null;
sendInvalidate("lcuStatus");
editStoreEntry("connectorStatus", null);
});

export interface AuthData {
Expand All @@ -57,13 +58,14 @@ export const compareFriends = async (oldFriends: FriendStats[], newFriends: Frie
if (
newFriend.division !== oldFriend.division ||
newFriend.tier !== oldFriend.tier ||
newFriend.leaguePoints !== oldFriend.leaguePoints
newFriend.leaguePoints !== oldFriend.leaguePoints ||
newFriend.miniSeriesProgress !== oldFriend.miniSeriesProgress
) {
changes.push({
...newFriend,
oldFriend,
toNotify: !!oldFriend.division,
windowsNotification: selectedFriends.current?.has(newFriend.puuid),
windowsNotification: store.selectedFriends?.has(newFriend.puuid),
});
}
});
Expand All @@ -85,7 +87,7 @@ export const postMessage = (payload: { summonerName: string; message: string })
const url = `/lol-game-client-chat/v1/instant-messages?summonerName=${encodeURI(
payload.summonerName
)}&message=${encodeURI(payload.message)}`;
return connectorStatus.api.post(url);
return store.lcu?.post(url);
};

export const getAllApexLeague = async () => {
Expand All @@ -103,6 +105,7 @@ export const getApexLeague = (tier: RankedStats["queues"][0]["tier"]) =>
///lol-ranked-stats/v1/stats/{summonerId}
export const getHelp = () => request("/help?format=Console");
export const getBuild = () => request("/system/v1/builds");
export const getRegionLocale = () => request<Locale>("/riotclient/region-locale");
export const getCurrentSummoner = () =>
request<CurrentSummoner>("/lol-summoner/v1/current-summoner");
export const getFriends = () => request<FriendDto[]>("/lol-chat/v1/friends");
Expand Down Expand Up @@ -153,4 +156,4 @@ export const getSwagger = () => request("/swagger/v2/swagger.json");

type AxiosMethod = "get" | "post" | "put" | "delete" | "patch";
export const request = async <T>(uri: string, method: AxiosMethod = "get") =>
(await connectorStatus.api[method]<T>(uri)).data as T;
(await store.lcu?.[method]<T>(uri))?.data as T;
2 changes: 1 addition & 1 deletion electron/LCU/types.ts → electron/features/lcu/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Friend } from "../entities/Friend";
import { Friend } from "../../entities/Friend";

export interface FriendDto extends Friend {
availability: string;
Expand Down
63 changes: 34 additions & 29 deletions electron/routes/friends.ts → electron/features/routes/friends.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ import { pick } from "@pastable/core";
import debug from "debug";
import { getManager } from "typeorm";
import { sendFriendList, sendInvalidate } from ".";
import { Friend } from "../entities/Friend";
import { FriendName } from "../entities/FriendName";
import { Ranking } from "../entities/Ranking";
import { FriendDto } from "../LCU/types";
import { editSelectedFriends, persistSelectedFriends, selectedFriends } from "../selection";
import { sendToClient } from "../utils";
import { Friend } from "../../entities/Friend";
import { FriendName } from "../../entities/FriendName";
import { Ranking } from "../../entities/Ranking";
import { FriendDto } from "../lcu/types";
import { editStoreEntry, store } from "../store";

const friendFields: (keyof FriendDto)[] = [
"gameName",
Expand Down Expand Up @@ -44,10 +43,17 @@ export const getFriendsAndRankingsFromDb = () => {
};

export const getFriendAndRankingsFromDb = (puuid: Friend["puuid"]) =>
getManager().findOne(Friend, {
where: { puuid },
relations: ["rankings", "friendNames", "notifications"],
});
getManager()
.createQueryBuilder(Friend, "friend")
.leftJoinAndSelect("friend.rankings", "rankings")
.leftJoinAndSelect("friend.friendNames", "friendNames")
.leftJoinAndSelect("friend.notifications", "notifications")
.orderBy("rankings.createdAt", "DESC")
.orderBy("notifications.createdAt", "DESC")
.orderBy("friendNames.createdAt", "DESC")
.where("friend.puuid = :puuid", { puuid })
.getOne();

export const getFriendsAndLastRankingFromDb = async () => {
const friends = await getFriendsAndRankingsFromDb();
return friends.map((friend) => {
Expand All @@ -62,18 +68,19 @@ export const getFriendsAndLastRankingFromDb = async () => {
});
};

export const getSelectedFriends = async () => Array.from(selectedFriends.current!);
export const toggleSelectFriends = async (puuids: Friend["puuid"][], newState: boolean) =>
editSelectedFriends(() =>
puuids.forEach((puuid) => selectedFriends.current?.[newState ? "add" : "delete"](puuid))
);
export const toggleSelectFriends = async (puuids: Friend["puuid"][], newState: boolean) => {
const newSelectedFriends = new Set(store.selectedFriends);

puuids.forEach((puuid) => newSelectedFriends?.[newState ? "add" : "delete"](puuid));
await editStoreEntry("selectedFriends", newSelectedFriends);
};

export const selectAllFriends = async (select: boolean) => {
const friends = await getFriendsFromDb();
return editSelectedFriends(() =>
friends.forEach((friend) =>
selectedFriends.current?.[select ? "add" : "delete"](friend.puuid)
)
);
const newSelectedFriends = new Set(store.selectedFriends);

friends.forEach((friend) => newSelectedFriends?.[select ? "add" : "delete"](friend.puuid));
await editStoreEntry("selectedFriends", newSelectedFriends);
};

const friendDtoToFriend = (friendDto: FriendDto): Partial<Friend> => ({
Expand All @@ -91,10 +98,6 @@ const friendDtoToFriend = (friendDto: FriendDto): Partial<Friend> => ({
]),
});

export const inGameFriends: { current: any[] } = {
current: null as any,
};

export const addOrUpdateFriends = async (friends: FriendDto[]) => {
const existingFriends = await getFriendsFromDb();
const manager = getManager();
Expand All @@ -103,13 +106,15 @@ export const addOrUpdateFriends = async (friends: FriendDto[]) => {

for (const friend of friends) {
if (
friend.lol.gameStatus !== "outOfGame" &&
!["outOfGame", "hosting_RANKED_SOLO_5x5", "spectating"].includes(
friend.lol.gameStatus
) &&
friend.lol.gameQueueType === "RANKED_SOLO_5x5"
) {
currentInGame.push({
...pick(friend, ["puuid", "gameName", "icon"]),
...pick(friend, ["puuid", "gameName", "icon", "name"]),
...pick(friend.lol, ["championId", "timeStamp", "gameStatus"]),
}); // championId: friend.lol.championId});
});
}
const friendDto = pick(friend, friendFields);
const existingFriend = existingFriends.find((ef) => ef.puuid === friend.puuid);
Expand Down Expand Up @@ -138,7 +143,8 @@ export const addOrUpdateFriends = async (friends: FriendDto[]) => {
await manager.save(manager.create(Friend, friendDtoToFriend(friendDto)));
}
}
inGameFriends.current = [...currentInGame];

await editStoreEntry("inGameFriends", [...currentInGame]);
sendInvalidate("friendList/in-game");
sendFriendList();
debug("add or update ended");
Expand All @@ -159,7 +165,6 @@ export const friendsApi = {
getFriendsAndRankingsFromDb,
getFriendAndRankingsFromDb,
getFriendsAndLastRankingFromDb,
getSelectedFriends,
toggleSelectFriends,
addOrUpdateFriends,
addRanking,
Expand Down
Loading