(untested) spectator implementation
This commit is contained in:
parent
9f6339ce48
commit
1907e9910d
4 changed files with 92 additions and 10 deletions
|
@ -3,6 +3,7 @@ import { ConsoleHelper } from "../ConsoleHelper";
|
|||
import { Channel } from "./objects/Channel";
|
||||
import { ChatManager } from "./ChatManager";
|
||||
import { Database } from "./objects/Database";
|
||||
import { DataStreamArray } from "./objects/DataStreamArray";
|
||||
import { LatLng } from "./objects/LatLng";
|
||||
import { LoginProcess } from "./LoginProcess";
|
||||
import { Packets } from "./enums/Packets";
|
||||
|
@ -10,17 +11,15 @@ import { replaceAll } from "./Util";
|
|||
import { readFileSync } from "fs";
|
||||
import { RedisClientType, createClient } from "redis";
|
||||
import { Request, Response } from "express";
|
||||
import { SpectatorManager } from "./SpectatorManager";
|
||||
import { UserArray } from "./objects/UserArray";
|
||||
import { User } from "./objects/User";
|
||||
import { DataStreamArray } from "./objects/DataStreamArray";
|
||||
import { MultiplayerManager } from "./MultiplayerManager";
|
||||
import { SharedContent } from "./interfaces/SharedContent";
|
||||
const config:Config = JSON.parse(readFileSync("./config.json").toString()) as Config;
|
||||
// TODO: Port osu-packet to TypeScript
|
||||
const osu = require("osu-packet");
|
||||
|
||||
|
||||
|
||||
const sharedContent:any = {};
|
||||
// NOTE: This function should only be used externaly in Binato.ts and in this file.
|
||||
export function GetSharedContent() : SharedContent {
|
||||
|
@ -53,6 +52,8 @@ chatManager.AddChatChannel("japanese", "Talk in exclusively Japanese");
|
|||
|
||||
const multiplayerManager:MultiplayerManager = sharedContent.mutiplayerManager = new MultiplayerManager(GetSharedContent());
|
||||
|
||||
const spectatorManager:SpectatorManager = new SpectatorManager(GetSharedContent());
|
||||
|
||||
let redisClient:RedisClientType;
|
||||
|
||||
async function subscribeToChannel(channelName:string, callback:(message:string) => void) {
|
||||
|
@ -97,7 +98,6 @@ import { Logout } from "./packets/Logout";
|
|||
import { UserPresence } from "./packets/UserPresence";
|
||||
import { UserStatsRequest } from "./packets/UserStatsRequest";
|
||||
import { UserPresenceBundle } from "./packets/UserPresenceBundle";
|
||||
import { Match } from "./objects/Match";
|
||||
|
||||
// User timeout interval
|
||||
setInterval(() => {
|
||||
|
@ -171,15 +171,15 @@ export async function HandleRequest(req:Request, res:Response, packet:Buffer) {
|
|||
break;
|
||||
|
||||
case Packets.Client_StartSpectating:
|
||||
//Spectator.startSpectatingUser(PacketUser, CurrentPacket.data);
|
||||
spectatorManager.startSpectating(PacketUser, CurrentPacket.data);
|
||||
break;
|
||||
|
||||
case Packets.Client_SpectateFrames:
|
||||
//Spectator.sendSpectatorFrames(PacketUser, CurrentPacket.data);
|
||||
spectatorManager.spectatorFrames(PacketUser, CurrentPacket.data);
|
||||
break;
|
||||
|
||||
case Packets.Client_StopSpectating:
|
||||
//Spectator.stopSpectatingUser(PacketUser);
|
||||
spectatorManager.stopSpectating(PacketUser);
|
||||
break;
|
||||
|
||||
case Packets.Client_SendPrivateMessage:
|
||||
|
|
79
server/SpectatorManager.ts
Normal file
79
server/SpectatorManager.ts
Normal file
|
@ -0,0 +1,79 @@
|
|||
import { DataStream } from "./objects/DataStream";
|
||||
import { SharedContent } from "./interfaces/SharedContent";
|
||||
import { User } from "./objects/User";
|
||||
const osu = require("osu-packet");
|
||||
|
||||
export class SpectatorManager {
|
||||
private sharedContent:SharedContent;
|
||||
|
||||
public constructor(sharedContent:SharedContent) {
|
||||
this.sharedContent = sharedContent;
|
||||
}
|
||||
|
||||
public startSpectating(user:User, userIdToSpectate:number) {
|
||||
const userToSpectate = this.sharedContent.users.getById(userIdToSpectate);
|
||||
if (userToSpectate === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use existing or create spectator stream
|
||||
let spectateStream:DataStream;
|
||||
if (userToSpectate.spectatorStream === undefined) {
|
||||
user.spectatorStream = spectateStream = userToSpectate.spectatorStream = this.sharedContent.streams.CreateStream(`spectator:${userToSpectate.username}`);
|
||||
} else {
|
||||
user.spectatorStream = spectateStream = userToSpectate.spectatorStream;
|
||||
}
|
||||
|
||||
user.spectatingUser = userToSpectate;
|
||||
|
||||
let osuPacketWriter = new osu.Bancho.Writer;
|
||||
|
||||
osuPacketWriter.SpectatorJoined(user.id);
|
||||
|
||||
userToSpectate.addActionToQueue(osuPacketWriter.toBuffer);
|
||||
|
||||
osuPacketWriter = new osu.Bancho.Writer;
|
||||
|
||||
osuPacketWriter.FellowSpectatorJoined(user.id);
|
||||
|
||||
spectateStream.Send(osuPacketWriter.toBuffer);
|
||||
}
|
||||
|
||||
// TODO: Interface for spectateFrameData
|
||||
public spectatorFrames(user:User, spectateFrameData:any) {
|
||||
if (user.spectatorStream === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const osuPacketWriter = new osu.Bancho.Writer;
|
||||
osuPacketWriter.SpectateFrames(spectateFrameData);
|
||||
|
||||
user.spectatorStream.Send(osuPacketWriter.toBuffer);
|
||||
}
|
||||
|
||||
public stopSpectating(user:User) {
|
||||
if (user.spectatingUser === undefined || user.spectatorStream === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const spectatedUser = user.spectatingUser;
|
||||
|
||||
let osuPacketWriter = new osu.Bancho.Writer;
|
||||
osuPacketWriter.SpectatorLeft(user.id);
|
||||
spectatedUser.addActionToQueue(osuPacketWriter.toBuffer);
|
||||
|
||||
const stream = user.spectatorStream;
|
||||
|
||||
stream.RemoveUser(user);
|
||||
user.spectatorStream = undefined;
|
||||
user.spectatingUser = undefined;
|
||||
|
||||
if (stream.IsActive) {
|
||||
osuPacketWriter = new osu.Bancho.Writer;
|
||||
osuPacketWriter.FellowSpectatorLeft(user.id);
|
||||
stream.Send(osuPacketWriter.toBuffer);
|
||||
} else {
|
||||
spectatedUser.spectatorStream = undefined;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,6 +18,10 @@ export class DataStream {
|
|||
this.removeWhenEmpty = removeWhenEmpty;
|
||||
}
|
||||
|
||||
public get IsActive() : boolean {
|
||||
return this.inactive;
|
||||
}
|
||||
|
||||
private checkInactive() {
|
||||
if (this.inactive) {
|
||||
throw `Stream ${this.name} is inactive (deleted) and cannot be used here.`;
|
||||
|
|
|
@ -26,13 +26,12 @@ export class User {
|
|||
|
||||
// Binato data
|
||||
public rankingMode:RankingModes = RankingModes.PP;
|
||||
public spectatorStream:DataStream | null = null;
|
||||
public spectatorStream?:DataStream;
|
||||
public spectatingUser?:User;
|
||||
|
||||
// osu! data
|
||||
public playMode:number = 0;
|
||||
public countryID:number = 0;
|
||||
//public spectators:Array; // TODO: Figure out if this was ever needed
|
||||
public spectating:number = -1;
|
||||
public location:LatLng = new LatLng(0, 0);
|
||||
public joinedChannels:Array<string> = new Array<string>();
|
||||
|
||||
|
|
Loading…
Reference in a new issue