-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #20 from DerTyp876/refactor_clean-up
Clean up project
- Loading branch information
Showing
11 changed files
with
3,457 additions
and
654 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
import { IAuthSenderPayload, IChannel, IClient, IConnection, ITS5ConnectionHandler, ITS5DataHandler, ITS5MessageHandler } from "@interfaces/teamspeak"; | ||
import { TS5DataHandler } from "./dataHandler"; | ||
import { TS5MessageHandler } from "./messageHandler"; | ||
|
||
|
||
// Establish connection to TS5 client | ||
// Main class | ||
export class TS5ConnectionHandler implements ITS5ConnectionHandler { | ||
ws: WebSocket; // Websocket connection to TS5 client | ||
authenticated = false; // Is the connection authenticated? | ||
remoteAppPort: number; // Port of TS5 client | ||
dataHandler: ITS5DataHandler; // Handles data/lists and states | ||
messageHandler: ITS5MessageHandler; // Handles messages received from TS5 client | ||
|
||
constructor( | ||
// Port of TS5 client | ||
remoteAppPort: number, | ||
|
||
// State setters for dataHandler | ||
setConnections: React.Dispatch<React.SetStateAction<IConnection[]>>, | ||
setChannels: React.Dispatch<React.SetStateAction<IChannel[]>>, | ||
setClients: React.Dispatch<React.SetStateAction<IClient[]>>, | ||
setActiveConnectionStateId: React.Dispatch<React.SetStateAction<number>>, | ||
) { | ||
// Create websocket connection to TS5 client | ||
this.remoteAppPort = remoteAppPort; | ||
this.ws = new WebSocket(`ws://localhost:${this.remoteAppPort}`); | ||
|
||
// Create dataHandler and messageHandler | ||
this.dataHandler = new TS5DataHandler(setConnections, setChannels, setClients); | ||
this.messageHandler = new TS5MessageHandler(this.ws, this.dataHandler, setActiveConnectionStateId); | ||
} | ||
|
||
reconnect() { | ||
console.log("Reconnecting...") | ||
this.ws.close(); | ||
|
||
this.ws = new WebSocket(`ws://localhost:${this.remoteAppPort}`); | ||
|
||
this.dataHandler.clearAll(); | ||
this.authenticated = false; | ||
this.connect(); | ||
} | ||
|
||
// Connect to TS5 client | ||
connect() { | ||
console.log('Connecting to TS5 client...'); | ||
console.log(localStorage.getItem("apiKey")) | ||
|
||
// Create authentication payload | ||
const initalPayload: IAuthSenderPayload = { | ||
type: "auth", | ||
payload: { | ||
identifier: "de.tealfire.obs", | ||
version: "1.0.0", | ||
name: "TS5 OBS Overlay", | ||
description: "A OBS overlay for TS5 by DerTyp876", | ||
content: { | ||
apiKey: localStorage.getItem("apiKey") ?? "", | ||
}, | ||
}, | ||
}; | ||
|
||
this.ws.onopen = () => { | ||
// Send authentication payload to TS5 client | ||
console.log("Sending auth payload...") | ||
this.ws.send(JSON.stringify(initalPayload)); | ||
}; | ||
|
||
this.ws.onclose = (event) => { | ||
console.log("WebSocket connection closed", event); | ||
|
||
// If the connection was closed before authentication, remove the API key from local storage | ||
// OBS weirdly caches the localstorage and is very stubborn about clearing it (even when clicken "Clear Cache") | ||
if (!this.authenticated) { | ||
console.log("WebSocket connection closed before authentication"); | ||
localStorage.removeItem("apiKey"); | ||
} | ||
|
||
setTimeout(() => { | ||
this.reconnect(); | ||
}, 2000); | ||
}; | ||
|
||
// Handle messages received from TS5 client | ||
// See TS5MessageHandler class | ||
this.ws.onmessage = (event) => { | ||
const data = JSON.parse(event.data); | ||
|
||
console.log(data) | ||
|
||
switch (data.type) { | ||
case "auth": | ||
this.messageHandler.handleAuthMessage(data); | ||
this.authenticated = true; | ||
break; | ||
case "clientMoved": | ||
this.messageHandler.handleClientMovedMessage(data); | ||
break; | ||
case "clientPropertiesUpdated": | ||
this.messageHandler.handleClientPropertiesUpdatedMessage(data); | ||
break; | ||
case "talkStatusChanged": | ||
this.messageHandler.handleTalkStatusChangedMessage(data); | ||
break; | ||
case "serverPropertiesUpdated": | ||
this.messageHandler.handleServerPropertiesUpdatedMessage(data); | ||
//this.ws.close(); | ||
break; | ||
case "connectStatusChanged": | ||
this.messageHandler.handleConnectStatusChangedMessage(data); | ||
break; | ||
case "clientSelfPropertyUpdated": | ||
this.messageHandler.handleClientSelfPropertyUpdatedMessage(data); | ||
break; | ||
case "channels": | ||
this.messageHandler.handleChannelsMessage(data); | ||
break; | ||
default: | ||
console.log(`No handler for event type: ${data.type}`); | ||
break; | ||
} | ||
}; | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
import { IConnection, IChannel, IClient, ITS5DataHandler } from "@interfaces/teamspeak"; | ||
|
||
|
||
/** | ||
* Handles data received from TS5 client (list of connections, channels and clients) | ||
* Updates the states of App.tsx | ||
*/ | ||
export class TS5DataHandler implements ITS5DataHandler { | ||
// Local lists of connections, channels and clients | ||
// These lists are used to keep track of the data, independent of the App.tsx state | ||
localConnections: IConnection[]; | ||
localChannels: IChannel[]; | ||
localClients: IClient[]; | ||
|
||
// State setters for App.tsx | ||
setConnections: React.Dispatch<React.SetStateAction<IConnection[]>>; | ||
setChannels: React.Dispatch<React.SetStateAction<IChannel[]>>; | ||
setClients: React.Dispatch<React.SetStateAction<IClient[]>>; | ||
|
||
constructor( | ||
// State setters for App.tsx | ||
setConnections: React.Dispatch<React.SetStateAction<IConnection[]>>, | ||
setChannels: React.Dispatch<React.SetStateAction<IChannel[]>>, | ||
setClients: React.Dispatch<React.SetStateAction<IClient[]>> | ||
) { | ||
this.setConnections = setConnections; | ||
this.setChannels = setChannels; | ||
this.setClients = setClients; | ||
|
||
this.localConnections = []; | ||
this.localChannels = []; | ||
this.localClients = []; | ||
} | ||
|
||
// Update App.tsx states | ||
private updateConnectionsState() { | ||
this.setConnections([...this.localConnections]); | ||
} | ||
|
||
private updateChannelsState() { | ||
this.setChannels([...this.localChannels]); | ||
} | ||
|
||
private updateClientsState() { | ||
this.setClients([...this.localClients]); | ||
} | ||
|
||
// Clear all data | ||
clearAll() { | ||
this.localConnections = []; | ||
this.localChannels = []; | ||
this.localClients = []; | ||
|
||
this.updateConnectionsState(); | ||
this.updateChannelsState(); | ||
this.updateClientsState(); | ||
} | ||
|
||
// Add data to local lists and update states | ||
addConnection(connection: IConnection) { | ||
console.log("Adding connection...", connection) | ||
|
||
const existingConnection: IConnection | undefined = this.localConnections.find((localConnection: IConnection) => localConnection.id === connection.id); | ||
|
||
if (existingConnection == undefined) { | ||
this.localConnections.push(connection); | ||
this.updateConnectionsState(); | ||
console.log("Connection added") | ||
} else { | ||
console.log("Connection already exists") | ||
} | ||
} | ||
|
||
addChannel(channel: IChannel) { | ||
console.log("Adding channel...", channel) | ||
const existingChannel: IChannel | undefined = this.localChannels.find((localChannel: IChannel) => localChannel.id === channel.id && localChannel.connection.id === channel.connection.id); | ||
|
||
if (existingChannel == undefined) { | ||
this.localChannels.push(channel); | ||
this.updateChannelsState(); | ||
console.log("Channel added") | ||
} else { | ||
console.log("Channel already exists") | ||
} | ||
} | ||
|
||
addClient(client: IClient) { | ||
console.log("Adding client...", client) | ||
const existingClient: IClient | undefined = this.localClients.find((localClient: IClient) => localClient.id === client.id && localClient.channel?.connection.id === client.channel?.connection.id); | ||
|
||
if (existingClient == undefined) { | ||
this.localClients.push(client); | ||
this.updateClientsState(); | ||
console.log("Client added") | ||
} else { | ||
console.log("Client already exists") | ||
} | ||
} | ||
|
||
// Update data in local lists and update states | ||
updateConnection(connection: IConnection) { | ||
console.log("Updating connection...", connection) | ||
const existingConnection: IConnection | undefined = this.localConnections.find((localConnection: IConnection) => localConnection.id === connection.id); | ||
|
||
if (existingConnection !== undefined) { | ||
this.localConnections[this.localConnections.indexOf(existingConnection)] = connection; | ||
this.updateConnectionsState(); | ||
console.log("Connection updated") | ||
} else { | ||
console.log("Connection does not exist") | ||
} | ||
} | ||
|
||
updateChannel(channel: IChannel) { | ||
console.log("Updating channel...", channel) | ||
const existingChannel: IChannel | undefined = this.localChannels.find((localChannel: IChannel) => localChannel.id === channel.id && localChannel.connection.id === channel.connection.id); | ||
|
||
if (existingChannel !== undefined) { | ||
this.localChannels[this.localChannels.indexOf(existingChannel)] = channel; | ||
this.updateChannelsState(); | ||
console.log("Channel updated") | ||
} else { | ||
console.log("Channel does not exist") | ||
} | ||
} | ||
|
||
updateClient(client: IClient) { | ||
console.log("Updating client...", client) | ||
const existingClient: IClient | undefined = this.localClients.find((localClient: IClient) => localClient.id === client.id && localClient.channel?.connection.id === client.channel?.connection.id); | ||
|
||
if (existingClient !== undefined) { | ||
this.localClients[this.localClients.indexOf(existingClient)] = client; | ||
this.updateClientsState(); | ||
console.log("Client updated") | ||
} else { | ||
console.log("Client does not exist") | ||
} | ||
} | ||
|
||
// Remove data from local lists and update states | ||
removeConnection(connection: IConnection) { | ||
console.log("Removing connection...", connection) | ||
const existingConnection: IConnection | undefined = this.localConnections.find((localConnection: IConnection) => localConnection.id === connection.id); | ||
|
||
if (existingConnection !== undefined) { | ||
this.localConnections.splice(this.localConnections.indexOf(existingConnection), 1); | ||
|
||
// Remove all channels and clients associated with the connection | ||
this.localChannels = this.localChannels.filter((localChannel: IChannel) => localChannel.connection.id !== connection.id); | ||
this.localClients = this.localClients.filter((localClient: IClient) => localClient.channel?.connection.id !== connection.id); | ||
|
||
this.updateChannelsState(); | ||
this.updateClientsState(); | ||
this.updateConnectionsState(); | ||
console.log("Connection removed") | ||
} else { | ||
console.log("Connection does not exist") | ||
} | ||
} | ||
|
||
removeChannel(channel: IChannel) { | ||
console.log("Removing channel...", channel) | ||
const existingChannel: IChannel | undefined = this.localChannels.find((localChannel: IChannel) => localChannel.id === channel.id && localChannel.connection.id === channel.connection.id); | ||
|
||
if (existingChannel !== undefined) { | ||
this.localChannels.splice(this.localChannels.indexOf(existingChannel), 1); | ||
|
||
// Remove all clients associated with the channel | ||
this.localClients = this.localClients.filter((localClient: IClient) => localClient.channel?.id !== channel.id); | ||
|
||
this.updateClientsState(); | ||
this.updateChannelsState(); | ||
console.log("Channel removed") | ||
} else { | ||
console.log("Channel does not exist") | ||
} | ||
} | ||
|
||
removeClient(client: IClient) { | ||
console.log("Removing client...", client) | ||
const existingClient: IClient | undefined = this.localClients.find((localClient: IClient) => localClient.id === client.id && localClient.channel?.connection.id === client.channel?.connection.id); | ||
|
||
if (existingClient !== undefined) { | ||
this.localClients.splice(this.localClients.indexOf(existingClient), 1); | ||
this.updateClientsState(); | ||
console.log("Client removed") | ||
} else { | ||
console.log("Client does not exist") | ||
} | ||
} | ||
|
||
// Helper functions | ||
getConnectionById(id: number): IConnection | undefined { | ||
return this.localConnections.find((connection: IConnection) => connection.id === id); | ||
} | ||
|
||
getChannelById(id: number, connectionId: number): IChannel | undefined { | ||
return this.localChannels.find((channel: IChannel) => channel.id === id && channel.connection?.id === connectionId); | ||
} | ||
|
||
getClientById(id: number, connectionId: number): IClient | undefined { | ||
return this.localClients.find((client: IClient) => client.id === id && client.channel?.connection.id === connectionId); | ||
} | ||
} |
Oops, something went wrong.