namespace Holo.Virtual.Rooms.Games { using Holo; using Holo.Virtual.Rooms.Pathfinding; using System; using System.Collections.ObjectModel; using System.Text; using System.Threading; internal class Game { private bbTileColor[,] bbTColor; private bbTileState[,] bbTState; private bool[,] Blocked; private int bX; private int bY; internal int[] enabledPowerups; private byte[,] Height; internal string Heightmap; internal int ID; internal bool isBattleBall; private int leftCountdownSeconds; internal int leftTime; internal gameLobby Lobby; internal int mapID; internal string Name; internal gamePlayer Owner; internal gameState State; internal Collection Subviewers; internal Collection[] Teams; internal int totalTime; private Thread updateHandler; internal Game(gameLobby Lobby, int ID, string Name, int mapID, int teamAmount, int[] enabledPowerups, gamePlayer Owner) { this.Subviewers = new Collection(); this.leftCountdownSeconds = Config.Game_Countdown_Seconds; this.Lobby = Lobby; this.ID = ID; this.Name = Name; this.mapID = mapID; this.Owner = Owner; this.enabledPowerups = enabledPowerups; this.totalTime = Config.Game_BattleBall_gameLength_Seconds; this.leftTime = Config.Game_BattleBall_gameLength_Seconds; this.isBattleBall = true; this.Teams = new Collection[teamAmount]; for (int i = 0; i < teamAmount; i++) { this.Teams[i] = new Collection(); } } internal Game(gameLobby Lobby, int ID, string Name, int mapID, int teamAmount, int totalTime, gamePlayer Owner) { this.Subviewers = new Collection(); this.leftCountdownSeconds = Config.Game_Countdown_Seconds; this.Lobby = Lobby; this.ID = ID; this.Name = Name; this.mapID = mapID; this.Owner = Owner; this.totalTime = totalTime; this.leftTime = totalTime; this.isBattleBall = false; this.Teams = new Collection[teamAmount]; for (int i = 0; i < teamAmount; i++) { this.Teams[i] = new Collection(); } } internal void Abort() { try { this.updateHandler.Abort(); } catch { } string data = "CmH"; for (int i = 0; i < this.Teams.Length; i++) { foreach (gamePlayer player in this.Teams[i]) { if (player.User != null) { if (this.State == gameState.Waiting) { player.User.sendData(data); } player.User.gamePlayer = null; } } } foreach (gamePlayer player2 in this.Subviewers) { if (player2.User != null) { if (this.State == gameState.Waiting) { player2.User.sendData(data); } player2.User.gamePlayer = null; } } } private void countDownTicker() { while (this.leftCountdownSeconds > 0) { this.leftCountdownSeconds--; Thread.Sleep(0x3e8); } for (int i = 0; i < this.Teams.Length; i++) { foreach (gamePlayer player in this.Teams[i]) { player.User._Tickets -= 2; player.User.sendData("A|" + player.User._Tickets); DB.runQuery(string.Concat(new object[] { "UPDATE users SET tickets = '", player.User._Tickets, "' WHERE id = '", player.User.userID, "' LIMIT 1" })); } } this.updateHandler = new Thread(new ThreadStart(this.updateLoop)); this.updateHandler.Start(); this.sendData("Cw" + Holo.Encoding.encodeVL64(this.totalTime)); } internal string getMap() { StringBuilder builder = new StringBuilder(); if (this.isBattleBall) { builder.Append("I" + Holo.Encoding.encodeVL64(this.leftCountdownSeconds) + Holo.Encoding.encodeVL64(Config.Game_Countdown_Seconds) + "H" + Holo.Encoding.encodeVL64(this.bX) + Holo.Encoding.encodeVL64(this.bY)); for (int i = 0; i < this.bY; i++) { for (int j = 0; j < this.bX; j++) { builder.Append(Holo.Encoding.encodeVL64((int) this.bbTColor[j, i]) + Holo.Encoding.encodeVL64((int) this.bbTState[j, i])); } } builder.Append("IH"); } else { builder.Append("holo.cast.not_finished"); } return builder.ToString(); } internal string getPlayers() { StringBuilder builder = null; StringBuilder builder2 = new StringBuilder(); Random random = new Random(DateTime.Now.Millisecond * this.totalTime); if (this.isBattleBall) { int i = 0; for (int j = 0; j < this.Teams.Length; j++) { foreach (gamePlayer player in this.Teams[j]) { Out.WriteLine(player.roomUID + "!"); builder2.Append(string.Concat(new object[] { "H", Holo.Encoding.encodeVL64(i), Holo.Encoding.encodeVL64(player.X), Holo.Encoding.encodeVL64(player.Y), Holo.Encoding.encodeVL64(player.H), Holo.Encoding.encodeVL64(player.Z), "HM", player.User._Username, Convert.ToChar(2), player.User._Mission, Convert.ToChar(2), player.User._Figure, Convert.ToChar(2), player.User._Sex, Convert.ToChar(2), Holo.Encoding.encodeVL64(player.teamID), Holo.Encoding.encodeVL64(player.roomUID) })); i++; } } builder = new StringBuilder("I" + Holo.Encoding.encodeVL64(this.leftCountdownSeconds) + Holo.Encoding.encodeVL64(Config.Game_Countdown_Seconds) + Holo.Encoding.encodeVL64(i)); builder.Append(builder2.ToString()); builder2 = null; builder.Append(Holo.Encoding.encodeVL64(this.bX) + Holo.Encoding.encodeVL64(this.bY)); for (int k = 0; k < this.bY; k++) { for (int m = 0; m < this.bX; m++) { builder.Append(Holo.Encoding.encodeVL64((int) this.bbTColor[m, k]) + Holo.Encoding.encodeVL64((int) this.bbTState[m, k])); } } builder.Append("IH"); } else { builder.Append("holo.cast.not_finished"); } return builder.ToString(); } private Coord[] getSurfaceTiles(Coord Start) { return null; } internal void movePlayer(gamePlayer Player, int fromTeamID, int toTeamID) { try { if (fromTeamID != -1) { this.Teams[fromTeamID].Remove(Player); } if (toTeamID != -1) { if (!this.Teams[toTeamID].Contains(Player)) { this.Teams[toTeamID].Add(Player); } Player.teamID = toTeamID; } else { this.Teams[Player.teamID].Remove(Player); Player.User.gamePlayer = null; } this.sendData("Ci" + this.Sub); } catch { } } internal void sendData(string Data) { for (int i = 0; i < this.Teams.Length; i++) { foreach (gamePlayer player in this.Teams[i]) { player.sendData(Data); } } if (this.State == gameState.Waiting) { foreach (gamePlayer player2 in this.Subviewers) { player2.sendData(Data); } } } internal void startGame() { this.State = gameState.Started; foreach (gamePlayer player in this.Subviewers) { player.sendData(this.Sub); } this.Heightmap = DB.runRead(string.Concat(new object[] { "SELECT heightmap FROM games_maps WHERE type = '", this.Lobby.Type, "' AND id = '", this.mapID, "'" })); string[] strArray = this.Heightmap.Split(new char[] { Convert.ToChar(13) }); this.bX = strArray[0].Length; this.bY = strArray.Length - 1; string[] strArray2 = null; if (this.isBattleBall) { this.bbTState = new bbTileState[this.bX, this.bY]; this.bbTColor = new bbTileColor[this.bX, this.bY]; strArray2 = DB.runRead("SELECT bb_tilemap FROM games_maps WHERE type = 'bb' AND id = '" + this.mapID + "'").Split(new char[] { Convert.ToChar(13) }); } this.Height = new byte[this.bX, this.bY]; this.Blocked = new bool[this.bX, this.bY]; for (int i = 0; i < this.bY; i++) { for (int k = 0; k < this.bX; k++) { string str = strArray[i].Substring(k, 1); if (str == "x") { this.Blocked[k, i] = true; if (this.isBattleBall) { this.bbTColor[k, i] = bbTileColor.Disabled; this.bbTState[k, i] = bbTileState.Sealed; } } else { this.Height[k, i] = Convert.ToByte(str); if (this.isBattleBall) { if (strArray2[i].Substring(k, 1) == "1") { this.bbTColor[k, i] = bbTileColor.Default; } else { this.bbTColor[k, i] = bbTileColor.Disabled; this.bbTState[k, i] = bbTileState.Sealed; } } } } } int num3 = 0; for (int j = 0; j < this.Teams.Length; j++) { if (this.Teams[j].Count != 0) { int[] numArray = DB.runReadRow(string.Concat(new object[] { "SELECT x,y,z FROM games_maps_playerspawns WHERE type = '", this.Lobby.Type, "' AND mapid = '", this.mapID, "' AND teamid = '", j, "'" }), null); int num5 = numArray[0]; int num6 = numArray[1]; byte num7 = (byte) numArray[2]; bool flag = false; foreach (gamePlayer player2 in this.Teams[j]) { player2.roomUID = num3; Label_03DD: try { while (this.Blocked[num5, num6]) { switch (num7) { case 0: case 2: if (flag) { num5--; } else { num5++; } goto Label_03DC; case 4: case 6: if (flag) { num6--; } else { num6++; } break; } Label_03DC:; } flag = !flag; } catch { flag = !flag; goto Label_03DD; } this.Blocked[num5, num6] = true; player2.X = num5; player2.Y = num6; player2.Z = num7; player2.H = this.Height[num5, num6]; player2.goalX = -1; player2.enteringGame = true; num3++; Out.WriteLine(string.Concat(new object[] { "Assigned spawnpoint [", num5, ",", num6, "] to player [", num3, ", team id: ", player2.teamID, "]" })); } } } this.sendData("Cq" + Holo.Encoding.encodeVL64(-1)); new Eucalypt.commonDelegate(this.countDownTicker).BeginInvoke(null, null); } internal bool teamHasSpace(int teamID) { try { int num = 0; switch (this.Teams.Length) { case 2: num = 6; break; case 3: num = 4; break; case 4: num = 3; break; } return (this.Teams[teamID].Count < num); } catch { return false; } } private void updateLoop() { if (this.isBattleBall) { int length = this.Teams.Length; int[] numArray = new int[length]; bool flag = false; int num2 = 0; int index = 0; while (index < length) { if (this.Teams[index].Count > 0) { num2++; } else { numArray[index] = -1; } index++; } Random random = new Random(DateTime.Now.Millisecond * length); while (this.leftTime > 0) { int[] numArray2 = new int[3]; StringBuilder builder = new StringBuilder(); StringBuilder builder2 = new StringBuilder(); StringBuilder builder3 = new StringBuilder(); index = 0; while (index < length) { foreach (gamePlayer player in this.Teams[index]) { builder.Append("H" + Holo.Encoding.encodeVL64(player.roomUID) + Holo.Encoding.encodeVL64(player.X) + Holo.Encoding.encodeVL64(player.Y) + Holo.Encoding.encodeVL64(player.H) + Holo.Encoding.encodeVL64(player.Z) + "HM"); if (player.bbColorTile) { player.bbColorTile = false; builder2.Append(Holo.Encoding.encodeVL64(player.X) + Holo.Encoding.encodeVL64(player.Y) + Holo.Encoding.encodeVL64((int) this.bbTColor[player.X, player.Y]) + Holo.Encoding.encodeVL64((int) this.bbTState[player.X, player.Y])); numArray2[1]++; } if (player.goalX != -1) { Coord coord = gamePathfinder.getNextStep(player.X, player.Y, player.goalX, player.goalY); if ((coord.X != -1) && !this.Blocked[coord.X, coord.Y]) { numArray2[2]++; builder3.Append("J" + Holo.Encoding.encodeVL64(player.roomUID) + Holo.Encoding.encodeVL64(coord.X) + Holo.Encoding.encodeVL64(coord.Y)); if ((coord.X == player.goalX) && (coord.Y == player.goalY)) { player.goalX = -1; } this.Blocked[player.X, player.Y] = false; this.Blocked[coord.X, coord.Y] = true; player.Z = Rotation.Calculate(player.X, player.Y, coord.X, coord.Y); player.X = coord.X; player.Y = coord.Y; player.H = this.Height[coord.X, coord.Y]; if (this.bbTState[coord.X, coord.Y] != bbTileState.Sealed) { if (this.bbTColor[coord.X, coord.Y] == (bbTileColor)player.teamID) { this.bbTState[coord.X, coord.Y]++; } else { this.bbTState[coord.X, coord.Y] = bbTileState.Touched; this.bbTColor[coord.X, coord.Y] = (bbTileColor) player.teamID; } int num4 = 0; switch (((int) this.bbTState[coord.X, coord.Y])) { case 1: num4 = num2; break; case 2: num4 = num2 * 3; break; case 3: num4 = num2 * 5; break; case 4: num4 = num2 * 7; break; } numArray[player.teamID] += num4; player.Score += num4; player.bbColorTile = true; } } else { player.goalX = -1; } } numArray2[0]++; } index++; } string str = "H" + Holo.Encoding.encodeVL64(length); index = 0; while (index < length) { str = str + Holo.Encoding.encodeVL64(numArray[index]); index++; } this.sendData("Ct" + Holo.Encoding.encodeVL64(numArray2[0]) + builder.ToString() + Holo.Encoding.encodeVL64(numArray2[1]) + builder2.ToString() + str + "I" + Holo.Encoding.encodeVL64(numArray2[2]) + builder3.ToString()); if (flag) { this.leftTime--; } flag = !flag; Thread.Sleep(470); } this.State = gameState.Ended; StringBuilder builder4 = new StringBuilder("Cx" + Holo.Encoding.encodeVL64(Config.Game_scoreWindow_restartGame_Seconds) + Holo.Encoding.encodeVL64(length)); for (index = 0; index < length; index++) { int count = this.Teams[index].Count; if (count > 0) { builder4.Append(Holo.Encoding.encodeVL64(count)); foreach (gamePlayer player in this.Teams[index]) { builder4.Append(Holo.Encoding.encodeVL64(player.roomUID)); if (player.User != null) { DB.runQuery(string.Concat(new object[] { "UPDATE users SET bb_playedgames = bb_playedgames + 1,bb_totalpoints = bb_totalpoints + ", player.Score, " WHERE id = '", player.User.userID, "' LIMIT 1" })); builder4.Append(player.User._Username + Convert.ToChar(2)); } else { builder4.Append("M"); } builder4.Append(Holo.Encoding.encodeVL64(player.Score)); } builder4.Append(Holo.Encoding.encodeVL64(numArray[index])); } else { builder4.Append("M"); } } this.sendData(builder4.ToString()); } } internal bool Launchable { get { int num = 0; for (int i = 0; i < this.Teams.Length; i++) { if (this.Teams[i].Count != 0) { num++; } } return (num > 1); } } internal string Sub { get { int num; StringBuilder builder = new StringBuilder(Holo.Encoding.encodeVL64((int) this.State)); if (this.Launchable) { builder.Append("I"); } else { builder.Append("H"); } builder.Append(string.Concat(new object[] { this.Name, Convert.ToChar(2), Holo.Encoding.encodeVL64(this.Owner.roomUID), this.Owner.User._Username, Convert.ToChar(2) })); if (!this.isBattleBall) { builder.Append(Holo.Encoding.encodeVL64(this.totalTime)); } builder.Append(Holo.Encoding.encodeVL64(this.mapID) + Holo.Encoding.encodeVL64(0) + Holo.Encoding.encodeVL64(this.Teams.Length)); for (num = 0; num < this.Teams.Length; num++) { builder.Append(Holo.Encoding.encodeVL64(this.Teams[num].Count)); foreach (gamePlayer player in this.Teams[num]) { builder.Append(Holo.Encoding.encodeVL64(player.roomUID) + player.User._Username + Convert.ToChar(2)); } } if (this.isBattleBall) { for (num = 0; num < this.enabledPowerups.Length; num++) { builder.Append(this.enabledPowerups[num] + ","); } builder.Append("9" + Convert.ToChar(2)); } else { builder.Append(Holo.Encoding.encodeVL64(this.leftTime) + Holo.Encoding.encodeVL64(this.mapID)); } return builder.ToString(); } } private enum bbTileColor { Blue = 1, Default = -1, Disabled = -2, Green = 3, Red = 0, Yellow = 2 } private enum bbTileState { Default, Touched, Clicked, Pressed, Sealed } internal enum gameState { Waiting, Started, Ended } } }