/// <summary> /// Creates a new game /// </summary> public void CreateGame() { var gameName = UI.GameNameTextbox.text; if (gameName.Length >= MinGameNameLength) { LobbyManager.CreateMatch(gameName, 2); UI.GameNameTextbox.text = string.Empty; } }
public void HandleRawPacket(MemoryStream receivedStream) { this.LastPacketTime = Environment.TickCount; while (!receivedStream.IsInEnd()) { Commands command = (Commands)receivedStream.ReadUInt16(); receivedStream.Position += 1; //skip 1 byte uint packetLength = receivedStream.ReadUInt32(); if (packetLength > receivedStream.Length - receivedStream.Position) { Debug.WriteLine("Invalid packet!! x.x"); PlayerManager.DisconnectPlayer(this.Id, DisconnectReason.Kick); return; } var reader = new SerializationReader(new MemoryStream(receivedStream.Read((int)packetLength))); Debug.WriteLine("[{2}] Command received: {0} [{1}]", command.ToString().Contains("_")?command.ToString().Split('_')[1]:command.ToString(), Utils.ByteArrayRepr((reader.BaseStream as MemoryStream).ToArray()), this.Username); switch (command) { case Commands.IN_LocalUserState: this.Status = new bUserStatus(reader); this.currentMode = Status.playMode; this.GetModeData((int)this.currentMode); QueueCommand(Commands.OUT_UpdateUserState, this.SerializableStats); break; case Commands.IN_IrcMessage: bIRCMessage message = new bIRCMessage(reader); PlayerManager.QueueCommandForAll(Commands.OUT_IrcMessage, new bIRCMessage(this.Username, message.Target, message.Message) { SenderId = this.Id }, exclude: this.Id); //TODO: Better command parse switch (message.Message) { case "!sendbanchorestart": const int delay = 20000; PlayerManager.QueueCommandForAll(Commands.const_86, delay); break; case "!closeosu": this.QueueCommand(Commands.OUT_Ping, 0); //lol, i can use this for ban break; case "!togglelock": this.currentMatch?.SetLocked(!this.currentMatch.Locked); break; case "!abort": this.currentMatch?.FinishMatch(true); break; case "!start": this.currentMatch?.StartMatch(); break; case "!givemehost": this.currentMatch?.SetHost(this); break; case "!targetmod": this.currentMatch?.SetMods(Mods.Target); break; case "!automod": this.currentMatch?.SetMods(Mods.Autoplay); //does nothing in gameplay >_> break; } break; case Commands.IN_Logout: PlayerManager.DisconnectPlayer(this, DisconnectReason.Logout); break; case Commands.IN_UNK03: //getlocaluserdata? //getallplayerstoload? //what the hell is this? QueueCommand(Commands.OUT_UserForLoadBundle, PlayerManager.PlayersIds.ToArray()); //TODO: Improve? break; case Commands.IN_HeartBit: break; //Do anything with this? case Commands.IN_SpectatePlayer: { Player player = PlayerManager.GetPlayerById(reader.ReadInt32()); if (player == null) { break; } if (this.Spectating != null) { if (this.Spectating.Id == player.Id) { break; } this.Spectating.RemoveSpectator(this.Id); this.Spectating = null; } player.AddSpectator(this); Spectating = player; //TODO: Spectator channel //TODO: Spectator see others spectators break; } case Commands.IN_StopSpectate: this.Spectating?.RemoveSpectator(this.Id); this.Spectating = null; break; case Commands.IN_SpectateFrames: var replay = new bReplayBuffer(reader); foreach (Player spectator in this.Spectators) { if (replay.enum0_0 == Enum0.Start && spectator.Status.beatmapHash != this.Status.beatmapHash) { spectator.QueueCommand(Commands.OUT_UpdateUserState, this.SerializableStats); } spectator.QueueCommand(Commands.OUT_SpectateFrames, replay); } break; case Commands.IN_CantSpectate: //No has map this.Spectating?.SpectatorNoHasMap(this.Id); break; case Commands.IN_IrcMessagePrivate: //TODO: IrcMessagePrivate break; case Commands.IN_LobbyPart: LobbyManager.ExitLobby(this.Id); break; case Commands.IN_LobbyJoin: LobbyManager.EnterLobby(this); break; case Commands.IN_MatchCreate: LobbyManager.CreateMatch(this, new bMatchData(reader)); break; case Commands.IN_MatchJoin: var intstr = new bIntStr(reader); if (!LobbyManager.TryEnterMatch(this, intstr.@int, intstr.str)) { QueueCommand(Commands.OUT_MatchJoinFail); } break; case Commands.IN_MatchLeave: currentMatch?.RemovePlayer(this.Id); break; case Commands.IN_MatchChangeSlot: if (this.currentMatch?.Locked == false) { currentMatch.MovePlayerSlot(this.Id, reader.ReadInt32()); } break; case Commands.IN_MatchReady: if (this.currentMatch?.Locked == false) { currentMatch.SetReady(true, this.Id); } break; case Commands.IN_MatchNotReady: if (this.currentMatch?.Locked == false) { currentMatch.SetReady(false, this.Id); } break; case Commands.IN_MatchLockSlot: if (this.currentMatch?.IsHost(this.Id) == true) { currentMatch.LockSlot(reader.ReadInt32()); } break; case Commands.IN_MatchChangeSettings: case Commands.IN_MatchChangePassword: if (this.currentMatch?.IsHost(this.Id) == true) { currentMatch.SetMatchData(new bMatchData(reader)); } break; case Commands.IN_MatchStart: if (this.currentMatch?.IsHost(this.Id) == true) { currentMatch.StartMatch(); } break; case Commands.IN_MatchScoreUpdate: if (this.currentMatch != null && this.IsMultiplaying) { try { currentMatch.OnPlayerScoreUpdate(this.Id, new bScoreData(reader)); } catch {} //NOTE: Sometimes it throw an exception, lol } break; case Commands.IN_ChannelJoin: QueueCommand(Commands.OUT_ChannelRevoked, reader.ReadString()); break; case Commands.IN_MatchComplete: if (this.currentMatch != null && this.IsMultiplaying) { this._matchPlayFinished = true; this.currentMatch.OnPlayerEndMatch(); } break; case Commands.IN_MatchChangeMods: if (this.currentMatch?.Locked == false) { this.currentMatch.SetMods(this.Id, (Mods)reader.ReadInt32()); } break; case Commands.IN_MatchLoadComplete: if (this.currentMatch != null && this.IsMultiplaying) { this._matchLoadFinished = true; this.currentMatch.OnPlayerEndLoad(); } break; case Commands.IN_MatchNoBeatmap: currentMatch?.SetHasMap(false, this.Id); break; case Commands.IN_MatchFailed: if (this.currentMatch != null && this.IsMultiplaying) { currentMatch.OnPlayerFail(this.Id); } break; case Commands.IN_MatchHasBeatmap: currentMatch?.SetHasMap(true, this.Id); break; case Commands.IN_MatchSkipRequest: if (this.currentMatch != null && this.IsMultiplaying) { this._matchSkipRequested = true; this.currentMatch.OnPlayerSkip(this.Id); } break; case Commands.IN_MatchTransferHost: if (this.currentMatch?.IsHost(this.Id) == true) { currentMatch.SetHost(reader.ReadInt32()); } break; case Commands.IN_GetUsersStats: { //To get status list? int[] playerList = reader.ReadInts(); foreach (var playerId in playerList) { if (playerId == this.Id) { continue; } Player player = PlayerManager.GetPlayerById(playerId); if (player != null) { QueueCommand(Commands.OUT_UpdateUserState, player.SerializableStats); } } break; } case Commands.IN_GetUsersInfo: { //To Load Player List? int[] playerList = reader.ReadInts(); foreach (var playerId in playerList) { Player player = PlayerManager.GetPlayerById(playerId); if (player != null) { QueueCommand(Commands.OUT_UpdateUserInfo, new bUserInfo(player.Id, player.Username, player.TimeZone, (byte)player.CountryId, player.Tags, player.currentMode, player.Longitude, player.Latitude, 1)); } else { QueueCommand(Commands.OUT_UserQuit, playerId); } } break; } case Commands.const_79: //NOTE: idk what is break; case Commands.IN_AwayMessage: //TODO: AwayMessage break; case Commands.IN_FriendAdd: //TODO: FriendAdd break; case Commands.IN_FriendRemove: //TODO: FriendRemove break; //TODO: UserToggleBlockNonFriendPM //TODO: BanchoSwitchTourneyServer case Commands.IN_InvitePlayer: { Player player = PlayerManager.GetPlayerById(reader.ReadInt32()); //TODO: Send using IRC player?.QueueCommand(Commands.OUT_IrcMessagePrivate, new bIRCMessage(this.Username, "", $"Come join my multiplayer match: [osump://{this.currentMatch.MatchData.matchId}/ {this.currentMatch.MatchData.gameName}]") { SenderId = this.Id }); break; } case Commands.const_98: //Content: GameBase.GameTime //NOTE: This is an packet that is received apparently when more than 256 users are sended by UserForLoad break; default: Debug.WriteLine("Undefined command: {0} [{1}]", command.ToString().Split('_')[1], Utils.ByteArrayRepr((reader.BaseStream as MemoryStream).ToArray())); break; } } }