protected override void OnMessage(MessageEventArgs e) { Program.LogMsg($"Getting Lock..", Discord.LogSeverity.Critical, $"Con::{REF}"); if (!OnlineLock.WaitOne(6 * 1000)) { Program.LogMsg($"Failed Lock..", Discord.LogSeverity.Critical, $"Con::{REF}"); Context.WebSocket.Close(CloseStatusCode.ServerError, "Unable to get lock"); return; } Program.LogMsg($"Got Lock..", Discord.LogSeverity.Critical, $"Con::{REF}"); try { log($"{REF} >>> {e.Data}"); Program.LogMsg($"{e.Data}", Discord.LogSeverity.Critical, REF); var jobj = JObject.Parse(e.Data); var packet = new ChessPacket(jobj); handleMessage(packet); } catch (Exception ex) { Program.LogMsg($"ChessCon:{Player?.Name ?? "na"}", ex); } finally { OnlineLock.Release(); Program.LogMsg($"Released Lock..", Discord.LogSeverity.Critical, $"Con::{REF}"); } }
public void Broadcast(ChessPacket p) { log($"{REF} === {p.ToString()}"); string data = p.ToString(); foreach (var pl in ChessService.CurrentGame.GetPlayers()) { if (pl is ChessAIPlayer ai) { ai.recievePacket(p); } else { try { pl.Send(data); } catch (Exception ex) { Program.LogMsg($"{ex}", Discord.LogSeverity.Warning, $"Send-{pl.ID}-{pl.Player?.Name ?? ""}"); } } } }
public virtual void Send(ChessPacket p) { log($"{REF} <<< {p.ToString()}"); this.Send(p.ToString()); }
void handleMessage(ChessPacket ping) { if (ChessService.CurrentGame == null || ChessService.CurrentGame.HasEnded) { Send(new ChessPacket(PacketId.GameEnd, new JObject())); return; } if (Player != null) { handleInGame(ping); return; } using var db = DB(); if (ping.Id == PacketId.ConnRequest) { Send(new ChessPacket(PacketId.Log, ping.Content)); var token = ping.Content["token"].ToObject <string>(); bool usesAntiCheat = ping.Content["cheat"].ToObject <bool>(); Player = db.Players.FirstOrDefault(x => x.VerifyOnlineReference == token); if (Player == null) { Context.WebSocket.Close(CloseStatusCode.InvalidData, "Player token invalid"); return; } if (Player.IsBuiltInAccount) { Context.WebSocket.Close(CloseStatusCode.Normal, "Built in account"); return; } if (Player.IsBanned) { Context.WebSocket.Close(CloseStatusCode.Normal, "Banned"); return; } if (Player.Removed) { Context.WebSocket.Close(CloseStatusCode.Normal, "Removed from Leaderboard"); return; } var existing = ChessService.CurrentGame.GetPlayer(Player.Id); if (existing != null) { this.Side = existing.Side; try { existing.Sessions.CloseSession(existing.ID, CloseStatusCode.PolicyViolation, "You joined with another client; replacing"); } catch { } if (this.Side == PlayerSide.White) { ChessService.CurrentGame.White = this; if (!usesAntiCheat) { ChessService.CurrentGame.UsesAntiCheat = false; } } else if (this.Side == PlayerSide.Black) { ChessService.CurrentGame.Black = this; if (!usesAntiCheat) { ChessService.CurrentGame.UsesAntiCheat = false; } } else { ChessService.CurrentGame.Spectators.RemoveAll(x => x.Player?.Id == Player.Id); ChessService.CurrentGame.Spectators.Add(this); } doJoin(); return; } var type = ping.Content["mode"].ToObject <string>(); if (type == "join") { if (CurrentGame.White == null) { CurrentGame.White = this; Side = PlayerSide.White; if (!usesAntiCheat) { ChessService.CurrentGame.UsesAntiCheat = false; } ChessS.LogChnl(new Discord.EmbedBuilder() .WithTitle("White Player") .WithDescription("Joined: " + Player.Name) .WithColor(usesAntiCheat ? Discord.Color.Green : Discord.Color.Red) , ChessS.DiscussionChannel); } else if (CurrentGame.Black == null) { Side = PlayerSide.Black; CurrentGame.Black = this; CurrentGame.InnerGame = new OtherGame(); ChessS.LogChnl(new Discord.EmbedBuilder() .WithTitle("Black Player") .WithDescription("Joined: " + Player.Name) .WithColor(usesAntiCheat ? Discord.Color.Green : Discord.Color.Red) , ChessS.DiscussionChannel); } else { Context.WebSocket.Close(CloseStatusCode.Normal, "Game is full"); return; } } else if (type == "spectate") { CurrentGame.Spectators.Add(this); ChessS.LogChnl(new Discord.EmbedBuilder() .WithTitle("Spectator").WithDescription("Joined: " + Player.Name), ChessS.DiscussionChannel); } doJoin(); } }
void handleInGame(ChessPacket ping) { if (ping.Id == PacketId.MoveRequest) { var r = new OtherGame.Move(); var g = CurrentGame; string sFrom = ping.Content["from"].ToObject <string>(); string sTo = ping.Content["to"].ToObject <string>(); if (!(Side == PlayerSide.White && g.InnerGame.turn == "w" || Side == PlayerSide.Black && g.InnerGame.turn == "b")) { Send(new ChessPacket(PacketId.MoveRequestRefuse, new MoveRefuse($"{sFrom} -> {sTo}", $"It is not your turn").ToJson())); return; } r.from = g.InnerGame.parseAlgebraic(sFrom); r.to = g.InnerGame.parseAlgebraic(sTo); var promVal = ping.Content["promote"]; if (promVal != null) { r.promotion = getPieceSimple(promVal.ToObject <int>()); } var legalMoves = g.InnerGame.generate_moves(new Dictionary <string, string>() { { "legal", "true" }, { "square", r.from.ToString() } }); OtherGame.Move?legalMove = null; foreach (var mv in legalMoves) { if (mv.from == r.from && mv.to == r.to) { if (!string.IsNullOrWhiteSpace(mv.promotion) && !string.IsNullOrWhiteSpace(r.promotion)) { if (mv.promotion != r.promotion) { continue; } } if (!string.IsNullOrWhiteSpace(mv.promotion) && string.IsNullOrWhiteSpace(r.promotion)) { if (mv.promotion != "q") { continue; } } if (string.IsNullOrWhiteSpace(mv.promotion) && !string.IsNullOrWhiteSpace(r.promotion)) { continue; } legalMove = mv; break; } } if (legalMove.HasValue == false) { Send(new ChessPacket(PacketId.MoveRequestRefuse, new MoveRefuse($"{sFrom} -> {sTo}", $"No legal move to that location").ToJson())); return; } g.InnerGame.make_move(legalMove.Value); g.InnerGame.registerMoveMade(); Program.LogMsg("Player made move", Discord.LogSeverity.Error, "Player"); ChessService.CurrentGame.updateBoard(); Broadcast(new ChessPacket(PacketId.MoveMade, ping.Content)); CheckGameEnd(); } else if (ping.Id == PacketId.IdentRequest) { var id = ping.Content["id"].ToObject <int>(); var player = CurrentGame.GetPlayer(id); var jobj = ping.Content; jobj["player"] = player?.ToJson() ?? JObject.FromObject(null); Send(new ChessPacket(PacketId.PlayerIdent, jobj)); } else if (ping.Id == PacketId.RequestScreen) { if (Player.Permission.HasFlag(ChessPerm.Moderator)) { var player = CurrentGame.GetPlayer(ping.Content["id"].ToObject <int>()); if (player != null) { player.ExpectDemand = true; player.Send(new ChessPacket(PacketId.DemandScreen, new JObject())); } } } else if (ping.Id == PacketId.RequestGameEnd) { var id = ping.Content["id"].ToObject <int>(); var player = id == 0 ? null : ChessService.CurrentGame.GetPlayer(id); var end = id == 0 ? GameEndCondition.Draw($"A-Drawn by {Player.Name}") : GameEndCondition.Win(player, $"A-Won by {Player.Name}"); ChessService.CurrentGame.DeclareWinner(end); } else if (ping.Id == PacketId.RequestProcesses) { if (Player.Permission.HasFlag(ChessPerm.Moderator)) { var player = CurrentGame.GetPlayer(ping.Content["id"].ToObject <int>()); if (player != null) { player.ExpectDemand = true; player.Send(new ChessPacket(PacketId.DemandProcesses, new JObject())); } } } else if (ping.Id == PacketId.ResignRequest) { ChessConnection opponent; if (Side == PlayerSide.White) { opponent = ChessService.CurrentGame.Black; } else if (Side == PlayerSide.Black) { opponent = ChessService.CurrentGame.White; } else { // spectators can't resign. return; } ChessService.CurrentGame.DeclareWinner(GameEndCondition.Win(opponent, "Resigned")); } else if (ping.Id == PacketId.RequestRevertMove) { if (Player.Permission.HasFlag(ChessPerm.Moderator)) { CurrentGame.InnerGame.undo_move(); Broadcast(new ChessPacket(PacketId.MoveReverted, ping.Content)); } } }