Skip to content

Commit

Permalink
Add uuids for better reconection
Browse files Browse the repository at this point in the history
Kick zombie users with same uuids.

Minimal node version is 14.
  • Loading branch information
RblSb committed Aug 15, 2024
1 parent 38cc0a1 commit 4ac52a4
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 45 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Default channel example: https://synctube.onrender.com/

### Setup
- Open `4200` port in your router settings (port is customizable)
- `npm install ws` in this project folder ([NodeJS](https://nodejs.org) required)
- `npm install ws` in this project folder ([NodeJS 14+](https://nodejs.org) required)
- Run `node build/server.js`
- Open showed "Local" link for yourself and send "Global" link to friends

Expand All @@ -34,7 +34,7 @@ As alternative, you can install Docker and run:
> docker run --rm -it -p 4200:4200 -v ${PWD}/user:/usr/src/app/user synctube
> ```
or
or
> ```shell
> docker compose up -d
Expand Down
98 changes: 63 additions & 35 deletions build/server.js

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,8 @@
"homepage": "https://github.com/RblSb/SyncTube#readme",
"dependencies": {
"ws": "^8.17.1"
},
"engines": {
"node": ">=14.17.0"
}
}
8 changes: 5 additions & 3 deletions res/client.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/Client.hx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class Client {
public final ws:WebSocket;
public final req:IncomingMessage;
public final id:Int;
public var uuid:String;
public var isAlive = true;
#end
public var name:String;
Expand Down
1 change: 1 addition & 0 deletions src/Types.hx
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ typedef FlashbackItem = {
typedef WsEvent = {
type:WsEventType,
?connected:{
uuid:String,
config:Config,
history:Array<Message>,
clients:Array<ClientData>,
Expand Down
1 change: 1 addition & 0 deletions src/client/ClientSettings.hx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package client;

typedef ClientSettings = {
version:Int,
uuid:Null<String>,
name:String,
hash:String,
isExtendedPlayer:Bool,
Expand Down
8 changes: 7 additions & 1 deletion src/client/Main.hx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class Main {

final defaults:ClientSettings = {
version: SETTINGS_VERSION,
uuid: null,
name: "",
hash: "",
isExtendedPlayer: false,
Expand Down Expand Up @@ -124,7 +125,8 @@ class Main {
final port = Browser.location.port;
final colonPort = port.length > 0 ? ':$port' : port;
final path = Browser.location.pathname;
ws = new WebSocket('$protocol//$host$colonPort$path');
final query = settings.uuid == null ? "" : '?uuid=${settings.uuid}';
ws = new WebSocket('$protocol//$host$colonPort$path$query');
ws.onmessage = onMessage;
ws.onopen = () -> {
disconnectNotification?.stop();
Expand Down Expand Up @@ -585,6 +587,10 @@ class Main {

function onConnected(data:WsEvent):Void {
final connected = data.connected;

settings.uuid = connected.uuid;
Settings.write(settings);

globalIp = connected.globalIp;
setConfig(connected.config);
if (connected.isUnknownClient) {
Expand Down
31 changes: 27 additions & 4 deletions src/server/Main.hx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ import haxe.Timer;
import haxe.crypto.Sha256;
import js.Node.__dirname;
import js.Node.process;
import js.node.Crypto;
import js.node.Http;
import js.node.http.IncomingMessage;
import js.node.url.URL;
import js.npm.ws.Server as WSServer;
import js.npm.ws.WebSocket;
import json2object.ErrorUtils;
Expand Down Expand Up @@ -378,13 +380,35 @@ class Main {
}
}

function randomUuid():String {
return (Crypto : Dynamic).randomUUID();
}

function getUrlUuid(link:String):Null<String> {
try {
if (link.startsWith('/')) link = 'http://127.0.0.1$link';
final url = new URL(link);
return url.searchParams.get("uuid");
} catch (e) {
return null;
}
}

function onConnect(ws:WebSocket, req:IncomingMessage):Void {
final uuid = getUrlUuid(req.url) ?? randomUuid();
final oldClient = clients.find(client -> client.uuid == uuid);
if (oldClient != null) {
send(oldClient, {type: KickClient});
onMessage(oldClient, {type: Disconnected}, true);
}

final ip = clientIp(req);
final id = freeIds.length > 0 ? freeIds.shift() : clients.length;
final name = 'Guest ${id + 1}';
trace(Date.now().toString(), '$name connected ($ip)');
final isAdmin = config.localAdmins && req.socket.localAddress == ip;
final client = new Client(ws, req, id, name, 0);
client.uuid = uuid;
client.isAdmin = isAdmin;
clients.push(client);
ws.on("pong", () -> client.isAlive = true);
Expand Down Expand Up @@ -444,6 +468,7 @@ class Main {
send(client, {
type: Connected,
connected: {
uuid: client.uuid,
config: config,
history: messages,
isUnknownClient: true,
Expand Down Expand Up @@ -490,8 +515,7 @@ class Main {
case BanClient:
if (!checkPermission(client, BanClientPerm)) return;
final name = data.banClient.name;
final bannedClient = clients.getByName(name);
if (bannedClient == null) return;
final bannedClient = clients.getByName(name) ?? return;
if (client.name == name || bannedClient.isAdmin) {
serverMessage(client, "adminsCannotBeBannedError");
return;
Expand All @@ -517,8 +541,7 @@ class Main {
case KickClient:
if (!checkPermission(client, BanClientPerm)) return;
final name = data.kickClient.name;
final kickedClient = clients.getByName(name);
if (kickedClient == null) return;
final kickedClient = clients.getByName(name) ?? return;
if (client.name != name && kickedClient.isAdmin) {
serverMessage(client, "adminsCannotBeBannedError");
return;
Expand Down

0 comments on commit 4ac52a4

Please sign in to comment.