public bool Start() { //Setup the variable toggles varBindingsInitialize(); int tmpMaxPlayers = 16; // Read in from the config file. DatafileWriter dataFile = new DatafileWriter("server.config.txt"); if (dataFile.Data.ContainsKey("winningcash")) winningCashAmount = uint.Parse(dataFile.Data["winningcash"], System.Globalization.CultureInfo.InvariantCulture); if (dataFile.Data.ContainsKey("includelava")) includeLava = bool.Parse(dataFile.Data["includelava"]); if (dataFile.Data.ContainsKey("orefactor")) oreFactor = uint.Parse(dataFile.Data["orefactor"], System.Globalization.CultureInfo.InvariantCulture); if (dataFile.Data.ContainsKey("maxplayers")) tmpMaxPlayers = (int)Math.Min(32, uint.Parse(dataFile.Data["maxplayers"], System.Globalization.CultureInfo.InvariantCulture)); if (dataFile.Data.ContainsKey("public")) varSet("public", bool.Parse(dataFile.Data["public"]), true); if (dataFile.Data.ContainsKey("servername")) varSet("name", dataFile.Data["servername"], true); if (dataFile.Data.ContainsKey("sandbox")) varSet("sandbox", bool.Parse(dataFile.Data["sandbox"]), true); if (dataFile.Data.ContainsKey("notnt")) varSet("tnt", !bool.Parse(dataFile.Data["notnt"]), true); if (dataFile.Data.ContainsKey("sphericaltnt")) varSet("stnt", bool.Parse(dataFile.Data["sphericaltnt"]), true); if (dataFile.Data.ContainsKey("insanelava")) varSet("insanelava", bool.Parse(dataFile.Data["insanelava"]), true); if (dataFile.Data.ContainsKey("shockspreadslava")) varSet("sspreads", bool.Parse(dataFile.Data["shockspreadslava"]), true); if (dataFile.Data.ContainsKey("roadabsorbs")) varSet("roadabsorbs", bool.Parse(dataFile.Data["roadabsorbs"]), true); if (dataFile.Data.ContainsKey("minelava")) varSet("minelava", bool.Parse(dataFile.Data["minelava"]), true); if (dataFile.Data.ContainsKey("levelname")) levelToLoad = dataFile.Data["levelname"]; if (dataFile.Data.ContainsKey("greeter")) varSet("greeter", dataFile.Data["greeter"], true); bool autoannounce = true; if (dataFile.Data.ContainsKey("autoannounce")) autoannounce = bool.Parse(dataFile.Data["autoannounce"]); // Load the ban-list. banList = LoadBanList(); // Load the admin-list admins = LoadAdminList(); if (tmpMaxPlayers >= 0) varSet("maxplayers", tmpMaxPlayers, true); // Initialize the server. NetConfiguration netConfig = new NetConfiguration("InfiniminerPlus"); netConfig.MaxConnections = (int)varGetI("maxplayers"); netConfig.Port = 5565; netServer = new InfiniminerNetServer(netConfig); netServer.SetMessageTypeEnabled(NetMessageType.ConnectionApproval, true); //netServer.SimulatedMinimumLatency = 0.1f; //netServer.SimulatedLatencyVariance = 0.05f; //netServer.SimulatedLoss = 0.1f; //netServer.SimulatedDuplicates = 0.05f; netServer.Start(); // Initialize variables we'll use. NetBuffer msgBuffer = netServer.CreateBuffer(); NetMessageType msgType; NetConnection msgSender; // Store the last time that we did a flow calculation. DateTime lastFlowCalc = DateTime.Now; //Check if we should autoload a level if (dataFile.Data.ContainsKey("autoload") && bool.Parse(dataFile.Data["autoload"])) { blockList = new BlockType[MAPSIZE, MAPSIZE, MAPSIZE]; blockCreatorTeam = new PlayerTeam[MAPSIZE, MAPSIZE, MAPSIZE]; LoadLevel(levelToLoad); } else { // Calculate initial lava flows. ConsoleWrite("CALCULATING INITIAL LAVA FLOWS"); ConsoleWrite("TOTAL LAVA BLOCKS = " + newMap()); } //Caculate the shape of spherical tnt explosions CalculateExplosionPattern(); // Send the initial server list update. if (autoannounce) PublicServerListUpdate(true); lastMapBackup = DateTime.Now; // Main server loop! ConsoleWrite("SERVER READY"); while (keepRunning) { // Process any messages that are here. while (netServer.ReadMessage(msgBuffer, out msgType, out msgSender)) { try { switch (msgType) { case NetMessageType.ConnectionApproval: { Player newPlayer = new Player(msgSender, null); newPlayer.Handle = Defines.Sanitize(msgBuffer.ReadString()).Trim(); if (newPlayer.Handle.Length == 0) { newPlayer.Handle = "Player"; } string clientVersion = msgBuffer.ReadString(); if (clientVersion != Defines.INFINIMINER_VERSION) { msgSender.Disapprove("VER;" + Defines.INFINIMINER_VERSION); } else if (banList.Contains(newPlayer.IP)) { msgSender.Disapprove("BAN;"); }/* else if (playerList.Count == maxPlayers) { msgSender.Disapprove("FULL;"); }*/ else { if (admins.ContainsKey(newPlayer.IP)) newPlayer.admin = admins[newPlayer.IP]; playerList[msgSender] = newPlayer; //Check if we should compress the map for the client try { bool compression = msgBuffer.ReadBoolean(); if (compression) playerList[msgSender].compression = true; } catch { } toGreet.Add(msgSender); this.netServer.SanityCheck(msgSender); msgSender.Approve(); PublicServerListUpdate(true); } } break; case NetMessageType.StatusChanged: { if (!this.playerList.ContainsKey(msgSender)) { break; } Player player = playerList[msgSender]; if (msgSender.Status == NetConnectionStatus.Connected) { ConsoleWrite("CONNECT: " + playerList[msgSender].Handle + " ( " + playerList[msgSender].IP + " )"); SendCurrentMap(msgSender); SendPlayerJoined(player); PublicServerListUpdate(); } else if (msgSender.Status == NetConnectionStatus.Disconnected) { ConsoleWrite("DISCONNECT: " + playerList[msgSender].Handle); SendPlayerLeft(player, player.Kicked ? "WAS KICKED FROM THE GAME!" : "HAS ABANDONED THEIR DUTIES!"); if (playerList.ContainsKey(msgSender)) playerList.Remove(msgSender); PublicServerListUpdate(); } } break; case NetMessageType.Data: { if (!this.playerList.ContainsKey(msgSender)) { break; } Player player = playerList[msgSender]; //If player isnt arround we dont care anymore - Cbock //If player is suspected of modding ignore updates for this cycle - Cbock if (player.Kicked == true || player.Flagged == true) break; InfiniminerMessage dataType = (InfiniminerMessage)msgBuffer.ReadByte(); switch (dataType) { case InfiniminerMessage.ChatMessage: { // Read the data from the packet. ChatMessageType chatType = (ChatMessageType)msgBuffer.ReadByte(); string chatString = Defines.Sanitize(msgBuffer.ReadString()); if (!ProcessCommand(chatString, GetAdmin(playerList[msgSender].IP), playerList[msgSender])) { ConsoleWrite("CHAT: (" + player.Handle + ") " + chatString); // Append identifier information. if (chatType == ChatMessageType.SayAll) chatString = player.Handle + " (ALL): " + chatString; else chatString = player.Handle + " (TEAM): " + chatString; // Construct the message packet. NetBuffer chatPacket = netServer.CreateBuffer(); chatPacket.Write((byte)InfiniminerMessage.ChatMessage); chatPacket.Write((byte)((player.Team == PlayerTeam.Red) ? ChatMessageType.SayRedTeam : ChatMessageType.SayBlueTeam)); chatPacket.Write(chatString); // Send the packet to people who should recieve it. foreach (Player p in playerList.Values) { if (chatType == ChatMessageType.SayAll || chatType == ChatMessageType.SayBlueTeam && p.Team == PlayerTeam.Blue || chatType == ChatMessageType.SayRedTeam && p.Team == PlayerTeam.Red) if (p.NetConn.Status == NetConnectionStatus.Connected) netServer.SendMessage(chatPacket, p.NetConn, NetChannel.ReliableInOrder3); } } } break; case InfiniminerMessage.UseTool: { Vector3 playerPosition = msgBuffer.ReadVector3(); Vector3 playerHeading = msgBuffer.ReadVector3(); PlayerTools playerTool = (PlayerTools)msgBuffer.ReadByte(); BlockType blockType = (BlockType)msgBuffer.ReadByte(); switch (playerTool) { case PlayerTools.Pickaxe: //Modification to prevent client from ignoring axe cooldown times - Cbock updateTime = DateTime.Now - player.AxeUsed; if (updateTime.TotalSeconds < 0.1f) { player.Flagged = true; } else { player.AxeUsed = DateTime.Now; UsePickaxe(player, playerPosition, playerHeading); } break; case PlayerTools.ConstructionGun: //Modification to prevent client from ignoring gun cooldown times - Cbock updateTime = DateTime.Now - player.GunUsed; if (updateTime.TotalSeconds < 0.35f) { player.Flagged = true; } else { player.GunUsed = DateTime.Now; UseConstructionGun(player, playerPosition, playerHeading, blockType); } //End Mod break; case PlayerTools.DeconstructionGun: //Modification to prevent client from ignoring gun cooldown times - Cbock updateTime = DateTime.Now - player.GunUsed; if (updateTime.TotalSeconds < 0.35f) { player.Flagged = true; } else { player.GunUsed = DateTime.Now; UseDeconstructionGun(player, playerPosition, playerHeading); } //End Mod break; case PlayerTools.ProspectingRadar: UseSignPainter(player, playerPosition, playerHeading); break; case PlayerTools.Detonator: UseDetonator(player); break; } } break; case InfiniminerMessage.SelectClass: { PlayerClass playerClass = (PlayerClass)msgBuffer.ReadByte(); ConsoleWrite("SELECT_CLASS: " + player.Handle + ", " + playerClass.ToString()); switch (playerClass) { case PlayerClass.Engineer: player.OreMax = 350; player.WeightMax = 4; break; case PlayerClass.Miner: player.OreMax = 200; player.WeightMax = 8; break; case PlayerClass.Prospector: player.OreMax = 200; player.WeightMax = 4; break; case PlayerClass.Sapper: player.OreMax = 200; player.WeightMax = 4; break; } SendResourceUpdate(player); } break; case InfiniminerMessage.PlayerSetTeam: { PlayerTeam playerTeam = (PlayerTeam)msgBuffer.ReadByte(); ConsoleWrite("SELECT_TEAM: " + player.Handle + ", " + playerTeam.ToString()); player.Team = playerTeam; SendResourceUpdate(player); SendPlayerSetTeam(player); } break; case InfiniminerMessage.PlayerDead: { ConsoleWrite("PLAYER_DEAD: " + player.Handle); player.Ore = 0; player.Cash = 0; player.Weight = 0; player.Alive = false; SendResourceUpdate(player); SendPlayerDead(player); string deathMessage = msgBuffer.ReadString(); if (deathMessage != "") { msgBuffer = netServer.CreateBuffer(); msgBuffer.Write((byte)InfiniminerMessage.ChatMessage); msgBuffer.Write((byte)(player.Team == PlayerTeam.Red ? ChatMessageType.SayRedTeam : ChatMessageType.SayBlueTeam)); msgBuffer.Write(player.Handle + " " + deathMessage); foreach (NetConnection netConn in playerList.Keys) if (netConn.Status == NetConnectionStatus.Connected) netServer.SendMessage(msgBuffer, netConn, NetChannel.ReliableInOrder3); } } break; case InfiniminerMessage.PlayerAlive: { if (toGreet.Contains(msgSender)) { string greeting = varGetS("greeter"); greeting = greeting.Replace("[name]", playerList[msgSender].Handle); if (greeting != "") { NetBuffer greetBuffer = netServer.CreateBuffer(); greetBuffer.Write((byte)InfiniminerMessage.ChatMessage); greetBuffer.Write((byte)ChatMessageType.SayAll); greetBuffer.Write(Defines.Sanitize(greeting)); netServer.SendMessage(greetBuffer, msgSender, NetChannel.ReliableInOrder3); } toGreet.Remove(msgSender); } ConsoleWrite("PLAYER_ALIVE: " + player.Handle); player.Ore = 0; player.Cash = 0; player.Weight = 0; player.Alive = true; SendResourceUpdate(player); SendPlayerAlive(player); } break; case InfiniminerMessage.PlayerUpdate: { player.Position = msgBuffer.ReadVector3(); player.Heading = msgBuffer.ReadVector3(); // Code to pervent speed, no clipping, and flying mods - DCaudill // Find out if the player is in the air Vector3 footPosition = player.Position + new Vector3(0f, -1.5f, 0f); BlockType standingOnBlock = BlockAtPoint(new Vector3(footPosition.X, footPosition.Y, footPosition.Z)); bool inAir = false; if (standingOnBlock == BlockType.None && !CheckOnLadder(player)) inAir = true; // Update the players list of last 10 updates playerList[msgSender].UpdatePositionServer(player.Position, inAir, player.Alive, DateTime.Now); // Check for speed mods and kick if found if (CheckSpeed(player) && player.positionList.Count > 9) { KickPlayer(player.IP); SendServerMessage(player.Handle + " was kicked for speed mods, Sorry"); ConsoleWrite(player.Handle + " was kicked for speed mods, Sorry"); } // Check for flying mods and kick if found if (CheckFlying(player) && player.positionList.Count > 9) { KickPlayer(player.IP); SendServerMessage(player.Handle + " was kicked for flying, Sorry"); ConsoleWrite(player.Handle + " was kicked for flying mods, Sorry"); } // Check for no clipping mods and kick if found if (CheckNoClipping(player) && player.positionList.Count > 9) { KickPlayer(player.IP); SendServerMessage(player.Handle + " was kicked for no clipping, Sorry"); ConsoleWrite(player.Handle + " was kicked for no clipping, Sorry"); } player.Tool = (PlayerTools)msgBuffer.ReadByte(); player.UsingTool = msgBuffer.ReadBoolean(); SendPlayerUpdate(player); } break; case InfiniminerMessage.DepositOre: { DepositOre(player); foreach (Player p in playerList.Values) SendResourceUpdate(p); } break; case InfiniminerMessage.WithdrawOre: { WithdrawOre(player); foreach (Player p in playerList.Values) SendResourceUpdate(p); } break; case InfiniminerMessage.PlayerPing: { SendPlayerPing((uint)msgBuffer.ReadInt32()); } break; case InfiniminerMessage.PlaySound: { InfiniminerSound sound = (InfiniminerSound)msgBuffer.ReadByte(); Vector3 position = msgBuffer.ReadVector3(); PlaySound(sound, position); } break; } } break; } } catch { } } // Unflag all clients after data is finished being parsed - Cbock foreach (Player p in playerList.Values) { p.Flagged = false; } //Time to backup map? TimeSpan mapUpdateTimeSpan = DateTime.Now - lastMapBackup; if (mapUpdateTimeSpan.TotalMinutes > 5) { SaveLevel("autoBK.lvl"); } // Time to send a new server update? PublicServerListUpdate(); //It checks for public server / time span //Time to terminate finished map sending threads? TerminateFinishedThreads(); // Check for players who are in the zone to deposit. DepositForPlayers(); // Is it time to do a lava calculation? If so, do it! TimeSpan timeSpan = DateTime.Now - lastFlowCalc; if (timeSpan.TotalMilliseconds > 500) { DoLavaStuff(); lastFlowCalc = DateTime.Now; } // Handle console keypresses. while (Console.KeyAvailable) { ConsoleKeyInfo keyInfo = Console.ReadKey(); if (keyInfo.Key == ConsoleKey.Enter) ConsoleProcessInput(); else if (keyInfo.Key == ConsoleKey.Backspace) { if (consoleInput.Length > 0) consoleInput = consoleInput.Substring(0, consoleInput.Length - 1); ConsoleRedraw(); } else { consoleInput += keyInfo.KeyChar; ConsoleRedraw(); } } // Is the game over? if (winningTeam != PlayerTeam.None && !restartTriggered) { BroadcastGameOver(); restartTriggered = true; restartTime = DateTime.Now.AddSeconds(10); } // Restart the server? if (restartTriggered && DateTime.Now > restartTime) { SaveLevel("autosave_" + (UInt64)DateTime.Now.ToBinary() + ".lvl"); netServer.Shutdown("The server is restarting."); return true; } // Pass control over to waiting threads. Thread.Sleep(1); } MessageAll("Server going down NOW!"); netServer.Shutdown("The server was terminated."); return false; }
public bool Start() { //Setup the variable toggles varBindingsInitialize(); int tmpMaxPlayers = 16; // Read in from the config file. DatafileWriter dataFile = new DatafileWriter("server.config.txt"); if (dataFile.Data.ContainsKey("winningcash")) winningCashAmount = uint.Parse(dataFile.Data["winningcash"], System.Globalization.CultureInfo.InvariantCulture); if (dataFile.Data.ContainsKey("includelava")) includeLava = bool.Parse(dataFile.Data["includelava"]); if (dataFile.Data.ContainsKey("includewater")) includeLava = bool.Parse(dataFile.Data["includewater"]); if (dataFile.Data.ContainsKey("orefactor")) oreFactor = uint.Parse(dataFile.Data["orefactor"], System.Globalization.CultureInfo.InvariantCulture); if (dataFile.Data.ContainsKey("maxplayers")) tmpMaxPlayers = (int)Math.Min(32, uint.Parse(dataFile.Data["maxplayers"], System.Globalization.CultureInfo.InvariantCulture)); if (dataFile.Data.ContainsKey("public")) varSet("public", bool.Parse(dataFile.Data["public"]), true); if (dataFile.Data.ContainsKey("servername")) varSet("name", dataFile.Data["servername"], true); if (dataFile.Data.ContainsKey("sandbox")) varSet("sandbox", bool.Parse(dataFile.Data["sandbox"]), true); if (dataFile.Data.ContainsKey("notnt")) varSet("tnt", !bool.Parse(dataFile.Data["notnt"]), true); if (dataFile.Data.ContainsKey("sphericaltnt")) varSet("stnt", bool.Parse(dataFile.Data["sphericaltnt"]), true); if (dataFile.Data.ContainsKey("insane")) varSet("insane", bool.Parse(dataFile.Data["insane"]), true); if (dataFile.Data.ContainsKey("roadabsorbs")) varSet("roadabsorbs", bool.Parse(dataFile.Data["roadabsorbs"]), true); if (dataFile.Data.ContainsKey("minelava")) varSet("minelava", bool.Parse(dataFile.Data["minelava"]), true); if (dataFile.Data.ContainsKey("levelname")) levelToLoad = dataFile.Data["levelname"]; if (dataFile.Data.ContainsKey("greeter")) varSet("greeter", dataFile.Data["greeter"],true); bool autoannounce = true; if (dataFile.Data.ContainsKey("autoannounce")) autoannounce = bool.Parse(dataFile.Data["autoannounce"]); // Load the ban-list. banList = LoadBanList(); // Load the admin-list admins = LoadAdminList(); if (tmpMaxPlayers>=0) varSet("maxplayers", tmpMaxPlayers, true); // Initialize the server. NetConfiguration netConfig = new NetConfiguration("InfiniminerPlus"); netConfig.MaxConnections = (int)varGetI("maxplayers"); netConfig.Port = 5565; netServer = new InfiniminerNetServer(netConfig); netServer.SetMessageTypeEnabled(NetMessageType.ConnectionApproval, true); //netServer.SimulatedMinimumLatency = 0.5f; // netServer.SimulatedLatencyVariance = 0.05f; // netServer.SimulatedLoss = 0.2f; // netServer.SimulatedDuplicates = 0.05f; //netServer.Configuration.SendBufferSize = 2048000; //netServer.Start();//starts too early // Initialize variables we'll use. NetBuffer msgBuffer = netServer.CreateBuffer(); NetMessageType msgType; NetConnection msgSender; // Store the last time that we did a flow calculation. DateTime lastFlowCalc = DateTime.Now; DateTime lastFlowCalcZ = DateTime.Now;//temporary DateTime sysTimer = DateTime.Now; //Check if we should autoload a level if (dataFile.Data.ContainsKey("autoload") && bool.Parse(dataFile.Data["autoload"])) { blockList = new BlockType[MAPSIZE, MAPSIZE, MAPSIZE]; blockCreatorTeam = new PlayerTeam[MAPSIZE, MAPSIZE, MAPSIZE]; LoadLevel(levelToLoad); lavaBlockCount = 0; waterBlockCount = 0; int burstBlockCount = 0; for (ushort i = 0; i < MAPSIZE; i++) for (ushort j = 0; j < MAPSIZE; j++) for (ushort k = 0; k < MAPSIZE; k++) { if (blockList[i, j, k] == BlockType.Lava) { lavaBlockCount += 1; } else if (blockList[i, j, k] == BlockType.Water) { waterBlockCount += 1; } else if (blockList[i, j, k] == BlockType.MagmaBurst) { burstBlockCount += 1; } } ConsoleWrite(waterBlockCount + " water blocks, " + lavaBlockCount + " lava blocks, " + burstBlockCount + " possible bursts." ); } else { // Calculate initial lava flows. ConsoleWrite("CALCULATING INITIAL LIQUID BLOCKS"); newMap(); lavaBlockCount = 0; waterBlockCount = 0; int burstBlockCount = 0; for (ushort i = 0; i < MAPSIZE; i++) for (ushort j = 0; j < MAPSIZE; j++) for (ushort k = 0; k < MAPSIZE; k++) { if (blockList[i, j, k] == BlockType.Lava) { lavaBlockCount += 1; } else if (blockList[i, j, k] == BlockType.Water) { waterBlockCount += 1; } else if (blockList[i, j, k] == BlockType.MagmaBurst) { burstBlockCount += 1; } } ConsoleWrite(waterBlockCount + " water blocks, " + lavaBlockCount + " lava blocks, " + burstBlockCount + " possible bursts."); } //Caculate the shape of spherical tnt explosions CalculateExplosionPattern(); // Send the initial server list update. if (autoannounce) PublicServerListUpdate(true); lastMapBackup = DateTime.Now; DateTime lastFPScheck = DateTime.Now; double frameRate = 0; // Main server loop! netServer.Start(); ConsoleWrite("SERVER READY"); if (!physics.IsAlive) { ConsoleWrite("Physics thread is limp."); } while (keepRunning) { if (!physics.IsAlive) { ConsoleWrite("Physics thread died."); // physics.Abort(); // physics.Join(); //physics.Start(); } frameCount = frameCount + 1; if (lastFPScheck <= DateTime.Now - TimeSpan.FromMilliseconds(1000)) { lastFPScheck = DateTime.Now; frameRate = frameCount;// / gameTime.ElapsedTotalTime.TotalSeconds; if (sleeping == false && frameCount < 20) { ConsoleWrite("Heavy load: " + frameCount + " FPS"); } frameCount = 0; } // Process any messages that are here. while (netServer.ReadMessage(msgBuffer, out msgType, out msgSender)) { try { switch (msgType) { case NetMessageType.ConnectionApproval: { Player newPlayer = new Player(msgSender, null); newPlayer.Handle = Defines.Sanitize(msgBuffer.ReadString()).Trim(); if (newPlayer.Handle.Length == 0) { newPlayer.Handle = "Player"; } string clientVersion = msgBuffer.ReadString(); if (clientVersion != Defines.INFINIMINER_VERSION) { msgSender.Disapprove("VER;" + Defines.INFINIMINER_VERSION); } else if (banList.Contains(newPlayer.IP)) { msgSender.Disapprove("BAN;"); }/* else if (playerList.Count == maxPlayers) { msgSender.Disapprove("FULL;"); }*/ else { if (admins.ContainsKey(newPlayer.IP)) newPlayer.admin = admins[newPlayer.IP]; playerList[msgSender] = newPlayer; //Check if we should compress the map for the client try { bool compression = msgBuffer.ReadBoolean(); if (compression) playerList[msgSender].compression = true; } catch { } toGreet.Add(msgSender); this.netServer.SanityCheck(msgSender); msgSender.Approve(); PublicServerListUpdate(true); } } break; case NetMessageType.StatusChanged: { if (!this.playerList.ContainsKey(msgSender)) { break; } Player player = playerList[msgSender]; if (msgSender.Status == NetConnectionStatus.Connected) { if (sleeping == true) { sleeping = false; physicsEnabled = true; } ConsoleWrite("CONNECT: " + playerList[msgSender].Handle + " ( " + playerList[msgSender].IP + " )"); SendCurrentMap(msgSender); SendPlayerJoined(player); PublicServerListUpdate(); } else if (msgSender.Status == NetConnectionStatus.Disconnected) { ConsoleWrite("DISCONNECT: " + playerList[msgSender].Handle); SendPlayerLeft(player, player.Kicked ? "WAS KICKED FROM THE GAME!" : "HAS ABANDONED THEIR DUTIES!"); if (playerList.ContainsKey(msgSender)) playerList.Remove(msgSender); sleeping = true; foreach (Player p in playerList.Values) { sleeping = false; } if (sleeping == true) { ConsoleWrite("HIBERNATING"); physicsEnabled = false; } PublicServerListUpdate(); } } break; case NetMessageType.Data: { if (!this.playerList.ContainsKey(msgSender)) { break; } Player player = playerList[msgSender]; InfiniminerMessage dataType = (InfiniminerMessage)msgBuffer.ReadByte(); switch (dataType) { case InfiniminerMessage.ChatMessage: { // Read the data from the packet. ChatMessageType chatType = (ChatMessageType)msgBuffer.ReadByte(); string chatString = Defines.Sanitize(msgBuffer.ReadString()); if (!ProcessCommand(chatString,GetAdmin(playerList[msgSender].IP),playerList[msgSender])) { if (chatType == ChatMessageType.SayAll) ConsoleWrite("CHAT: (" + player.Handle + ") " + chatString); // Append identifier information. if (chatType == ChatMessageType.SayAll) chatString = player.Handle + " (ALL): " + chatString; else chatString = player.Handle + " (TEAM): " + chatString; // Construct the message packet. NetBuffer chatPacket = netServer.CreateBuffer(); chatPacket.Write((byte)InfiniminerMessage.ChatMessage); chatPacket.Write((byte)((player.Team == PlayerTeam.Red) ? ChatMessageType.SayRedTeam : ChatMessageType.SayBlueTeam)); chatPacket.Write(chatString); // Send the packet to people who should recieve it. foreach (Player p in playerList.Values) { if (chatType == ChatMessageType.SayAll || chatType == ChatMessageType.SayBlueTeam && p.Team == PlayerTeam.Blue || chatType == ChatMessageType.SayRedTeam && p.Team == PlayerTeam.Red) if (p.NetConn.Status == NetConnectionStatus.Connected) netServer.SendMessage(chatPacket, p.NetConn, NetChannel.ReliableInOrder3); } } } break; case InfiniminerMessage.UseTool: { Vector3 playerPosition = msgBuffer.ReadVector3(); Vector3 playerHeading = msgBuffer.ReadVector3(); PlayerTools playerTool = (PlayerTools)msgBuffer.ReadByte(); BlockType blockType = (BlockType)msgBuffer.ReadByte(); //getTo switch (playerTool) { case PlayerTools.Pickaxe: UsePickaxe(player, playerPosition, playerHeading); break; case PlayerTools.StrongArm: if (player.Class == PlayerClass.Miner) UseStrongArm(player, playerPosition, playerHeading); break; case PlayerTools.Smash: //if(player.Class == PlayerClass.Sapper) //UseSmash(player, playerPosition, playerHeading); break; case PlayerTools.ConstructionGun: UseConstructionGun(player, playerPosition, playerHeading, blockType); break; case PlayerTools.DeconstructionGun: UseDeconstructionGun(player, playerPosition, playerHeading); break; case PlayerTools.ProspectingRadar: UseSignPainter(player, playerPosition, playerHeading); break; case PlayerTools.Detonator: if (player.Class == PlayerClass.Sapper) UseDetonator(player); break; case PlayerTools.Remote: if (player.Class == PlayerClass.Engineer) UseRemote(player); break; case PlayerTools.SetRemote: if (player.Class == PlayerClass.Engineer) SetRemote(player); break; case PlayerTools.ThrowBomb: if (player.Class == PlayerClass.Sapper) ThrowBomb(player, playerPosition, playerHeading); break; case PlayerTools.ThrowRope: if (player.Class == PlayerClass.Prospector) ThrowRope(player, playerPosition, playerHeading); break; case PlayerTools.Hide: if (player.Class == PlayerClass.Prospector) Hide(player); break; } } break; case InfiniminerMessage.SelectClass: { PlayerClass playerClass = (PlayerClass)msgBuffer.ReadByte(); player.Alive = false; ConsoleWrite("SELECT_CLASS: " + player.Handle + ", " + playerClass.ToString()); switch (playerClass) { case PlayerClass.Engineer: player.Class = playerClass; player.OreMax = 200 + (uint)(ResearchComplete[(byte)player.Team, 2] * 20); player.WeightMax = 4 + (uint)(ResearchComplete[(byte)player.Team, 2]); player.HealthMax = 100 + (uint)(ResearchComplete[(byte)player.Team,1]*20); player.Health = player.HealthMax; for (int a = 0; a < 100; a++) { player.Content[a] = 0; } break; case PlayerClass.Miner://strong arm/throws blocks player.Class = playerClass; player.OreMax = 100 + (uint)(ResearchComplete[(byte)player.Team, 2] * 20); player.WeightMax = 10 + (uint)(ResearchComplete[(byte)player.Team, 2]); player.HealthMax = 100 + (uint)(ResearchComplete[(byte)player.Team, 1] * 20); player.Health = player.HealthMax; for (int a = 0; a < 100; a++) { player.Content[a] = 0; } break; case PlayerClass.Prospector://profiteer/has prospectron/stealth/climb/traps player.Class = playerClass; player.OreMax = 100 + (uint)(ResearchComplete[(byte)player.Team, 2] * 20); player.WeightMax = 6 + (uint)(ResearchComplete[(byte)player.Team, 2]); player.HealthMax = 100 + (uint)(ResearchComplete[(byte)player.Team, 1] * 20); player.Health = player.HealthMax; for (int a = 0; a < 100; a++) { player.Content[a] = 0; } break; case PlayerClass.Sapper://berserker/charge that knocks people and blocks away/repairs block player.Class = playerClass; player.OreMax = 100 + (uint)(ResearchComplete[(byte)player.Team, 2] * 20); player.WeightMax = 4 + (uint)(ResearchComplete[(byte)player.Team, 2]); player.HealthMax = 100 + (uint)(ResearchComplete[(byte)player.Team, 1] * 20); player.Health = player.HealthMax; for (int a = 0; a < 100; a++) { player.Content[a] = 0; } break; } SendResourceUpdate(player); SendContentUpdate(player); SendPlayerSetClass(player); } break; case InfiniminerMessage.PlayerSetTeam: { PlayerTeam playerTeam = (PlayerTeam)msgBuffer.ReadByte(); ConsoleWrite("SELECT_TEAM: " + player.Handle + ", " + playerTeam.ToString()); player.Team = playerTeam; player.Health = 0; player.Alive = false; Player_Dead(player, ""); SendResourceUpdate(player); SendPlayerSetTeam(player); } break; case InfiniminerMessage.PlayerDead: { string deathMessage = msgBuffer.ReadString(); if (player.Alive) { Player_Dead(player, deathMessage); } } break; case InfiniminerMessage.PlayerAlive: { if (toGreet.Contains(msgSender)) { string greeting = varGetS("greeter"); greeting = greeting.Replace("[name]", playerList[msgSender].Handle); if (greeting != "") { NetBuffer greetBuffer = netServer.CreateBuffer(); greetBuffer.Write((byte)InfiniminerMessage.ChatMessage); greetBuffer.Write((byte)ChatMessageType.SayAll); greetBuffer.Write(Defines.Sanitize(greeting)); netServer.SendMessage(greetBuffer, msgSender, NetChannel.ReliableInOrder3); } toGreet.Remove(msgSender); } ConsoleWrite("PLAYER_ALIVE: " + player.Handle); player.Ore = 0; player.Cash = 0; player.Weight = 0; player.Health = player.HealthMax; player.Alive = true; player.respawnTimer = DateTime.Now + TimeSpan.FromSeconds(5); SendResourceUpdate(player); SendPlayerAlive(player); } break; case InfiniminerMessage.PlayerRespawn: { SendPlayerRespawn(player);//new respawn } break; case InfiniminerMessage.PlayerUpdate: { if (player.Alive) { player.Position = Auth_Position(msgBuffer.ReadVector3(), player, true); player.Heading = Auth_Heading(msgBuffer.ReadVector3()); player.Tool = (PlayerTools)msgBuffer.ReadByte(); player.UsingTool = msgBuffer.ReadBoolean(); SendPlayerUpdate(player); } } break; case InfiniminerMessage.PlayerSlap: { if (player.Alive) { if (player.playerToolCooldown > DateTime.Now) { break;//discard fast packet } player.Position = Auth_Position(msgBuffer.ReadVector3(), player, true); player.Heading = Auth_Heading(msgBuffer.ReadVector3()); player.Tool = (PlayerTools)msgBuffer.ReadByte(); player.UsingTool = true; Auth_Slap(player, msgBuffer.ReadUInt32()); SendPlayerUpdate(player); player.playerToolCooldown = DateTime.Now + TimeSpan.FromSeconds((float)(player.GetToolCooldown(PlayerTools.Pickaxe))); if (player.Class == PlayerClass.Prospector && player.Content[5] > 0)//reveal when hit { player.Content[6] = 0;//uncharge player.Content[1] = 0;//reappear on radar SendPlayerContentUpdate(player, 1); player.Content[5] = 0;//sight SendContentSpecificUpdate(player, 5); SendContentSpecificUpdate(player, 6); SendPlayerContentUpdate(player, 5); SendServerMessageToPlayer("You have been revealed!", player.NetConn); EffectAtPoint(player.Position - Vector3.UnitY * 1.5f, 1); } } } break; case InfiniminerMessage.PlayerUpdate1://minus position { if (player.Alive) { player.Heading = Auth_Heading(msgBuffer.ReadVector3()); player.Tool = (PlayerTools)msgBuffer.ReadByte(); player.UsingTool = msgBuffer.ReadBoolean(); SendPlayerUpdate(player); } } break; case InfiniminerMessage.PlayerUpdate2://minus position and heading { if (player.Alive) { player.Tool = (PlayerTools)msgBuffer.ReadByte(); player.UsingTool = msgBuffer.ReadBoolean(); SendPlayerUpdate(player); } } break; case InfiniminerMessage.PlayerHurt://client speaks of fall damage { uint newhp = msgBuffer.ReadUInt32(); if (newhp < player.Health) { if (player.Team == PlayerTeam.Red) { DebrisEffectAtPoint((int)(player.Position.X), (int)(player.Position.Y), (int)(player.Position.Z), BlockType.SolidRed, 10 + (int)(player.Health - newhp)); } else { DebrisEffectAtPoint((int)(player.Position.X), (int)(player.Position.Y), (int)(player.Position.Z), BlockType.SolidBlue, 10 + (int)(player.Health - newhp)); } player.Health = newhp; if (player.Health < 1) { Player_Dead(player, "FELL TO THEIR DEATH!"); } } } break; case InfiniminerMessage.PlayerPosition://server not interested in clients complaints about position { } break; case InfiniminerMessage.PlayerInteract://client speaks of mashing on block { player.Position = Auth_Position(msgBuffer.ReadVector3(), player, true); uint btn = msgBuffer.ReadUInt32(); uint btnx = msgBuffer.ReadUInt32(); uint btny = msgBuffer.ReadUInt32(); uint btnz = msgBuffer.ReadUInt32(); //if (blockList[btnx, btny, btnz] == BlockType.Pump || blockList[btnx, btny, btnz] == BlockType.Pipe || blockList[btnx, btny, btnz] == BlockType.Generator || blockList[btnx, btny, btnz] == BlockType.Barrel || blockList[btnx, btny, btnz] == BlockType.Switch) //{ if (Get3DDistance((int)btnx, (int)btny, (int)btnz, (int)player.Position.X, (int)player.Position.Y, (int)player.Position.Z) < 4) { PlayerInteract(player,btn, btnx, btny, btnz); } //} } break; case InfiniminerMessage.DepositOre: { DepositOre(player); foreach (Player p in playerList.Values) SendResourceUpdate(p); } break; case InfiniminerMessage.WithdrawOre: { WithdrawOre(player); foreach (Player p in playerList.Values) SendResourceUpdate(p); } break; case InfiniminerMessage.PlayerPing: { if (player.Ping == 0) { SendPlayerPing((uint)msgBuffer.ReadInt32()); player.Ping = 2; } } break; case InfiniminerMessage.PlaySound: { InfiniminerSound sound = (InfiniminerSound)msgBuffer.ReadByte(); Vector3 position = msgBuffer.ReadVector3(); PlaySoundForEveryoneElse(sound, position,player); } break; case InfiniminerMessage.DropItem: { DropItem(player, msgBuffer.ReadUInt32()); } break; case InfiniminerMessage.GetItem: { //verify players position before get player.Position = Auth_Position(msgBuffer.ReadVector3(), player, false); GetItem(player,msgBuffer.ReadUInt32()); } break; } } break; } } catch { } } //Time to backup map? TimeSpan mapUpdateTimeSpan = DateTime.Now - lastMapBackup; if (mapUpdateTimeSpan.TotalMinutes > 5) { lastMapBackup = DateTime.Now; SaveLevel("autoBK.lvl"); } // Time to send a new server update? PublicServerListUpdate(); //It checks for public server / time span //Time to terminate finished map sending threads? TerminateFinishedThreads(); // Check for players who are in the zone to deposit. VictoryCheck(); // Is it time to do a lava calculation? If so, do it! TimeSpan timeSpan = DateTime.Now - sysTimer; if (timeSpan.TotalMilliseconds > 2000) { //ConsoleWrite("" + delta); sysTimer = DateTime.Now; //secondflow += 1; //if (secondflow > 2)//every 2nd flow, remove the vacuum that prevent re-spread //{ // EraseVacuum(); // secondflow = 0; //} if (randGen.Next(1, 4) == 3) { bool isUpdateOre = false; bool isUpdateCash = false; for (int a = 1; a < 3; a++) { if (artifactActive[a, 1] > 0)//material artifact { isUpdateOre = true; if (a == 1) { teamOreRed = teamOreRed + (uint)(10 * artifactActive[a, 1]); } else if (a == 2) { teamOreBlue = teamOreBlue + (uint)(10 * artifactActive[a, 1]); } } if (artifactActive[a, 5] > 0)//golden artifact { isUpdateCash = true; if (a == 1) { teamCashRed = teamCashRed + (uint)(2 * artifactActive[a, 5]); } else if (a == 2) { teamCashBlue = teamCashBlue + (uint)(2 * artifactActive[a, 5]); } } } if (isUpdateOre) foreach (Player p in playerList.Values) SendTeamOreUpdate(p); if(isUpdateCash) foreach (Player p in playerList.Values) SendTeamCashUpdate(p); } foreach (Player p in playerList.Values)//regeneration { if (p.Ping > 0) p.Ping--; if (p.Alive) { if (p.Content[10] == 1)//material artifact personal { if (randGen.Next(1, 4) == 3) { if (p.Ore < p.OreMax) { p.Ore += 10; if (p.Ore >= p.OreMax) p.Ore = p.OreMax; SendOreUpdate(p); } } } else if (p.Content[10] == 5)//golden artifact personal { if (p.Ore > 99) { if (p.Weight < p.WeightMax) { p.Weight++; p.Cash += 10; p.Ore -= 100; SendCashUpdate(p); SendWeightUpdate(p); SendOreUpdate(p); PlaySound(InfiniminerSound.CashDeposit, p.Position); } } } else if (p.Content[10] == 6)//storm artifact personal { if(artifactActive[(byte)((p.Team == PlayerTeam.Red) ? PlayerTeam.Blue : PlayerTeam.Red),6] == 0)//stored storm artifact makes team immune foreach (Player pt in playerList.Values) { if (p.Team != pt.Team && pt.Alive) { float distfromPlayer = (p.Position - pt.Position).Length(); if (distfromPlayer < 5) { pt.Health -= 5; if (pt.Health <= 0) { Player_Dead(pt,"WAS SHOCKED!"); } else SendHealthUpdate(pt); EffectAtPoint(pt.Position, 1); } } } } if (p.Health >= p.HealthMax) { p.Health = p.HealthMax; } else { p.Health = (uint)(p.Health + teamRegeneration[(byte)p.Team]); if (p.Content[10] == 3)//regeneration artifact { p.Health += 4; } if (p.Health >= p.HealthMax) { p.Health = p.HealthMax; } SendHealthUpdate(p); } if (p.Class == PlayerClass.Prospector) { if (p.Content[5] == 1) { p.Content[6]--; if (p.Content[6] < 1) { p.Content[1] = 0; SendPlayerContentUpdate(p, 1); p.Content[5] = 0;//sight SendContentSpecificUpdate(p, 5); SendPlayerContentUpdate(p, 5); SendServerMessageToPlayer("Hide must now recharge!", p.NetConn); EffectAtPoint(p.Position - Vector3.UnitY * 1.5f, 1); } } else { if(p.Content[6] < 4) p.Content[6]++; } } //if (p.Class == PlayerClass.Prospector)//temperature data//giving everyone //{ // p.Content[6] = 0; // for(int a = -5;a < 6;a++) // for(int b = -5;b < 6;b++) // for (int c = -5; c < 6; c++) // { // int nx = a + (int)p.Position.X; // int ny = b + (int)p.Position.Y; // int nz = c + (int)p.Position.Z; // if (nx < MAPSIZE - 1 && ny < MAPSIZE - 1 && nz < MAPSIZE - 1 && nx > 0 && ny > 0 && nz > 0) // { // BlockType block = blockList[nx,ny,nz]; // if (block == BlockType.Lava || block == BlockType.MagmaBurst || block == BlockType.MagmaVent) // { // p.Content[6] += 5 - Math.Abs(a) + 5 - Math.Abs(b) + 5 - Math.Abs(c); // } // } // } // if (p.Content[6] > 0) // SendContentSpecificUpdate(p, 6); //} } } } TimeSpan timeSpanZ = DateTime.Now - lastFlowCalcZ; serverTime[timeQueue] = DateTime.Now - lastTime;//timeQueue timeQueue += 1; if (timeQueue > 19) timeQueue = 0; lastTime = DateTime.Now; delta = (float)((serverTime[0].TotalSeconds + serverTime[1].TotalSeconds + serverTime[2].TotalSeconds + serverTime[3].TotalSeconds + serverTime[4].TotalSeconds + serverTime[5].TotalSeconds + serverTime[6].TotalSeconds + serverTime[7].TotalSeconds + serverTime[8].TotalSeconds + serverTime[9].TotalSeconds + serverTime[10].TotalSeconds + serverTime[11].TotalSeconds + serverTime[12].TotalSeconds + serverTime[13].TotalSeconds + serverTime[14].TotalSeconds + serverTime[15].TotalSeconds + serverTime[16].TotalSeconds + serverTime[17].TotalSeconds + serverTime[18].TotalSeconds + serverTime[19].TotalSeconds) / 20); Sunray(); if (timeSpanZ.TotalMilliseconds > 50) { lastFlowCalcZ = DateTime.Now; DoItems(); } //random diamond appearance if (sleeping == false) if (randGen.Next(1, 100000) == 2) { ushort diamondx = (ushort)randGen.Next(4, 57); ushort diamondy = (ushort)randGen.Next(3, 30); ushort diamondz = (ushort)randGen.Next(4, 57); if (blockList[diamondx, diamondy, diamondz] == BlockType.Dirt) { // ConsoleWrite("diamond spawned at " + diamondx + "/" + diamondy + "/" + diamondz); SetBlock(diamondx, diamondy, diamondz, BlockType.Diamond, PlayerTeam.None); blockListHP[diamondx, diamondy, diamondz] = BlockInformation.GetMaxHP(BlockType.Diamond); } } // Handle console keypresses. while (Console.KeyAvailable) { ConsoleKeyInfo keyInfo = Console.ReadKey(); if (keyInfo.Key == ConsoleKey.Enter) { if (consoleInput.Length > 0) ConsoleProcessInput(); } else if (keyInfo.Key == ConsoleKey.Backspace) { if (consoleInput.Length > 0) consoleInput = consoleInput.Substring(0, consoleInput.Length - 1); ConsoleRedraw(); } else { consoleInput += keyInfo.KeyChar; ConsoleRedraw(); } } // Is the game over? if (winningTeam != PlayerTeam.None && !restartTriggered) { BroadcastGameOver(); restartTriggered = true; restartTime = DateTime.Now.AddSeconds(10); } // Restart the server? if (restartTriggered && DateTime.Now > restartTime) { SaveLevel("autosave_" + (UInt64)DateTime.Now.ToBinary() + ".lvl"); netServer.Shutdown("The server is restarting."); Thread.Sleep(100); physics.Abort(); // mechanics.Abort(); return true;//terminates server thread completely } // Pass control over to waiting threads. if(sleeping == true) { Thread.Sleep(50); } else { Thread.Sleep(1); } } MessageAll("Server going down NOW!"); netServer.Shutdown("The server was terminated."); return false; }
public bool Start() { // Read in from the config file. DatafileLoader dataFile = new DatafileLoader("server.config.txt"); if (dataFile.Data.ContainsKey("winningcash")) winningCashAmount = uint.Parse(dataFile.Data["winningcash"], System.Globalization.CultureInfo.InvariantCulture); if (dataFile.Data.ContainsKey("includelava")) includeLava = bool.Parse(dataFile.Data["includelava"]); if (dataFile.Data.ContainsKey("orefactor")) oreFactor = uint.Parse(dataFile.Data["orefactor"], System.Globalization.CultureInfo.InvariantCulture); if (dataFile.Data.ContainsKey("maxplayers")) maxPlayers = Math.Min(32, uint.Parse(dataFile.Data["maxplayers"], System.Globalization.CultureInfo.InvariantCulture)); if (dataFile.Data.ContainsKey("public")) publicServer = bool.Parse(dataFile.Data["public"]); if (dataFile.Data.ContainsKey("servername")) serverName = dataFile.Data["servername"]; if (dataFile.Data.ContainsKey("sandbox")) sandboxMode = bool.Parse(dataFile.Data["sandbox"]); // Load the ban-list. banList = LoadBanList(); // Create our block world, translating the coordinates out of the cave generator (where Z points down) BlockType[, ,] worldData = CaveGenerator.GenerateCaveSystem(GlobalVariables.MAPSIZE, includeLava, oreFactor); blockList = new BlockType[GlobalVariables.MAPSIZE, GlobalVariables.MAPSIZE, GlobalVariables.MAPSIZE]; blockCreatorTeam = new PlayerTeam[GlobalVariables.MAPSIZE, GlobalVariables.MAPSIZE, GlobalVariables.MAPSIZE]; for (ushort i = 0; i < GlobalVariables.MAPSIZE; i++) for (ushort j = 0; j < GlobalVariables.MAPSIZE; j++) for (ushort k = 0; k < GlobalVariables.MAPSIZE; k++) { blockList[i, (ushort)(GlobalVariables.MAPSIZE - 1 - k), j] = worldData[i, j, k]; if(blockList[i, (ushort)(GlobalVariables.MAPSIZE - 1 - k), j] == BlockType.Lava) LavaBlocks.Add(new InfiniminerServer.Point3D() { X = (ushort)i, Y = (ushort)(GlobalVariables.MAPSIZE - 1 - k), Z = (ushort)j }, 0); blockCreatorTeam[i, j, k] = PlayerTeam.None; } // Initialize the server. NetConfiguration netConfig = new NetConfiguration("InfiniminerPlus"); netConfig.MaxConnections = (int)maxPlayers; netConfig.Port = 5565; netServer = new InfiniminerNetServer(netConfig); netServer.SetMessageTypeEnabled(NetMessageType.ConnectionApproval, true); //netServer.SimulatedMinimumLatency = 0.1f; //netServer.SimulatedLatencyVariance = 0.05f; //netServer.SimulatedLoss = 0.1f; //netServer.SimulatedDuplicates = 0.05f; netServer.Start(); // Initialize variables we'll use. NetBuffer msgBuffer = netServer.CreateBuffer(); NetMessageType msgType; NetConnection msgSender; // Store the last time that we did a flow calculation. DateTime lastFlowCalc = DateTime.Now; // Calculate initial lava flows. ConsoleWrite("CALCULATING INITIAL LAVA FLOWS"); while (DoLavaStuff()) ; ConsoleWrite("TOTAL LAVA BLOCKS = " + LavaBlocks.Count); // Send the initial server list update. PublicServerListUpdate(); // Main server loop! ConsoleWrite("SERVER READY"); while (keepRunning) { // Process any messages that are here. while (netServer.ReadMessage(msgBuffer, out msgType, out msgSender)) { switch (msgType) { case NetMessageType.ConnectionApproval: { Player newPlayer = new Player(msgSender, null); newPlayer.Handle = InfiniminerGame.Sanitize(msgBuffer.ReadString()).Trim(); if (newPlayer.Handle.Length == 0) { newPlayer.Handle = "Player"; } string clientVersion = msgBuffer.ReadString(); if (clientVersion != InfiniminerGame.INFINIMINER_VERSION) { msgSender.Disapprove("VER;" + InfiniminerGame.INFINIMINER_VERSION); } else if (banList.Contains(newPlayer.IP)) { msgSender.Disapprove("BAN;"); } else { playerList[msgSender] = newPlayer; this.netServer.SanityCheck(msgSender); msgSender.Approve(); } } break; case NetMessageType.StatusChanged: { if (!this.playerList.ContainsKey(msgSender)) { break; } Player player = playerList[msgSender]; if (msgSender.Status == NetConnectionStatus.Connected) { ConsoleWrite("CONNECT: " + playerList[msgSender].Handle); SendCurrentMap(msgSender); SendPlayerJoined(player); PublicServerListUpdate(); } else if (msgSender.Status == NetConnectionStatus.Disconnected) { ConsoleWrite("DISCONNECT: " + playerList[msgSender].Handle); SendPlayerLeft(player, player.Kicked ? "WAS KICKED FROM THE GAME!" : "HAS ABANDONED THEIR DUTIES!"); if (playerList.ContainsKey(msgSender)) playerList.Remove(msgSender); PublicServerListUpdate(); } } break; case NetMessageType.Data: { if (!this.playerList.ContainsKey(msgSender)) { break; } Player player = playerList[msgSender]; InfiniminerMessage dataType = (InfiniminerMessage)msgBuffer.ReadByte(); switch (dataType) { case InfiniminerMessage.ChatMessage: { // Read the data from the packet. ChatMessageType chatType = (ChatMessageType)msgBuffer.ReadByte(); string chatString = InfiniminerGame.Sanitize(msgBuffer.ReadString()); ConsoleWrite("CHAT: (" + player.Handle + ") " + chatString); // Append identifier information. if (chatType == ChatMessageType.SayAll) chatString = player.Handle + " (ALL): " + chatString; else chatString = player.Handle + " (TEAM): " + chatString; // Construct the message packet. NetBuffer chatPacket = netServer.CreateBuffer(); chatPacket.Write((byte)InfiniminerMessage.ChatMessage); chatPacket.Write((byte)((player.Team == PlayerTeam.Red) ? ChatMessageType.SayRedTeam : ChatMessageType.SayBlueTeam)); chatPacket.Write(chatString); // Send the packet to people who should recieve it. foreach (Player p in playerList.Values) { if (chatType == ChatMessageType.SayAll || chatType == ChatMessageType.SayBlueTeam && p.Team == PlayerTeam.Blue || chatType == ChatMessageType.SayRedTeam && p.Team == PlayerTeam.Red) if (p.NetConn.Status == NetConnectionStatus.Connected) netServer.SendMessage(chatPacket, p.NetConn, NetChannel.ReliableInOrder3); } } break; case InfiniminerMessage.UseTool: { Vector3 playerPosition = msgBuffer.ReadVector3(); Vector3 playerHeading = msgBuffer.ReadVector3(); PlayerTools playerTool = (PlayerTools)msgBuffer.ReadByte(); BlockType blockType = (BlockType)msgBuffer.ReadByte(); switch (playerTool) { case PlayerTools.Pickaxe: UsePickaxe(player, playerPosition, playerHeading); break; case PlayerTools.ConstructionGun: UseConstructionGun(player, playerPosition, playerHeading, blockType); break; case PlayerTools.DeconstructionGun: UseDeconstructionGun(player, playerPosition, playerHeading); break; case PlayerTools.ProspectingRadar: UseSignPainter(player, playerPosition, playerHeading); break; case PlayerTools.Detonator: UseDetonator(player); break; } } break; case InfiniminerMessage.SelectClass: { PlayerClass playerClass = (PlayerClass)msgBuffer.ReadByte(); ConsoleWrite("SELECT_CLASS: " + player.Handle + ", " + playerClass.ToString()); switch (playerClass) { case PlayerClass.Engineer: player.OreMax = 350; player.WeightMax = 4; break; case PlayerClass.Miner: player.OreMax = 200; player.WeightMax = 8; break; case PlayerClass.Prospector: player.OreMax = 200; player.WeightMax = 4; break; case PlayerClass.Sapper: player.OreMax = 200; player.WeightMax = 4; break; } SendResourceUpdate(player); } break; case InfiniminerMessage.PlayerSetTeam: { PlayerTeam playerTeam = (PlayerTeam)msgBuffer.ReadByte(); ConsoleWrite("SELECT_TEAM: " + player.Handle + ", " + playerTeam.ToString()); player.Team = playerTeam; SendResourceUpdate(player); SendPlayerSetTeam(player); } break; case InfiniminerMessage.PlayerDead: { ConsoleWrite("PLAYER_DEAD: " + player.Handle); player.Ore = 0; player.Cash = 0; player.Weight = 0; player.Alive = false; SendResourceUpdate(player); SendPlayerDead(player); string deathMessage = msgBuffer.ReadString(); if (deathMessage != "") { msgBuffer = netServer.CreateBuffer(); msgBuffer.Write((byte)InfiniminerMessage.ChatMessage); msgBuffer.Write((byte)(player.Team == PlayerTeam.Red ? ChatMessageType.SayRedTeam : ChatMessageType.SayBlueTeam)); msgBuffer.Write(player.Handle + " " + deathMessage); foreach (NetConnection netConn in playerList.Keys) if (netConn.Status == NetConnectionStatus.Connected) netServer.SendMessage(msgBuffer, netConn, NetChannel.ReliableInOrder3); } } break; case InfiniminerMessage.PlayerAlive: { ConsoleWrite("PLAYER_ALIVE: " + player.Handle); player.Ore = 0; player.Cash = 0; player.Weight = 0; player.Alive = true; SendResourceUpdate(player); SendPlayerAlive(player); } break; case InfiniminerMessage.PlayerUpdate: { player.Position = msgBuffer.ReadVector3(); player.Heading = msgBuffer.ReadVector3(); player.Tool = (PlayerTools)msgBuffer.ReadByte(); player.UsingTool = msgBuffer.ReadBoolean(); SendPlayerUpdate(player); } break; case InfiniminerMessage.DepositOre: { DepositOre(player); foreach (Player p in playerList.Values) SendResourceUpdate(p); } break; case InfiniminerMessage.WithdrawOre: { WithdrawOre(player); foreach (Player p in playerList.Values) SendResourceUpdate(p); } break; case InfiniminerMessage.PlayerPing: { SendPlayerPing((uint)msgBuffer.ReadInt32()); } break; case InfiniminerMessage.PlaySound: { InfiniminerSound sound = (InfiniminerSound)msgBuffer.ReadByte(); Vector3 position = msgBuffer.ReadVector3(); PlaySound(sound, position); } break; } } break; } } // Time to send a new server update? TimeSpan updateTimeSpan = DateTime.Now - lastServerListUpdate; if (updateTimeSpan.TotalMinutes > 5) PublicServerListUpdate(); // Check for players who are in the zone to deposit. DepositForPlayers(); // Is it time to do a lava calculation? If so, do it! TimeSpan timeSpan = DateTime.Now - lastFlowCalc; if (timeSpan.TotalMilliseconds > 500) { DoLavaStuff(); lastFlowCalc = DateTime.Now; } // Handle console keypresses. while (Console.KeyAvailable) { ConsoleKeyInfo keyInfo = Console.ReadKey(); if (keyInfo.Key == ConsoleKey.Enter) ConsoleProcessInput(); else if (keyInfo.Key == ConsoleKey.Backspace) { if (consoleInput.Length > 0) consoleInput = consoleInput.Substring(0, consoleInput.Length - 1); ConsoleRedraw(); } else { consoleInput += keyInfo.KeyChar; ConsoleRedraw(); } } // Is the game over? if (winningTeam != PlayerTeam.None && !restartTriggered) { BroadcastGameOver(); restartTriggered = true; restartTime = DateTime.Now.AddSeconds(10); } // Restart the server? if (restartTriggered && DateTime.Now > restartTime) { SaveLevel("autosave_" + (UInt64)DateTime.Now.ToBinary() + ".lvl"); netServer.Shutdown("The server is restarting."); return true; } // Pass control over to waiting threads. Thread.Sleep(1); } netServer.Shutdown("The server was terminated."); return false; }
public bool Start() { //Setup the variable toggles varBindingsInitialize(); int tmpMaxPlayers = 16; // Read in from the config file. DatafileWriter dataFile = new DatafileWriter("server.config.txt"); if (dataFile.Data.ContainsKey("winningcash")) winningCashAmount = uint.Parse(dataFile.Data["winningcash"], System.Globalization.CultureInfo.InvariantCulture); if (dataFile.Data.ContainsKey("includelava")) includeLava = bool.Parse(dataFile.Data["includelava"]); if (dataFile.Data.ContainsKey("orefactor")) oreFactor = uint.Parse(dataFile.Data["orefactor"], System.Globalization.CultureInfo.InvariantCulture); if (dataFile.Data.ContainsKey("maxplayers")) tmpMaxPlayers = (int)Math.Min(32, uint.Parse(dataFile.Data["maxplayers"], System.Globalization.CultureInfo.InvariantCulture)); if (dataFile.Data.ContainsKey("public")) varSet("public", bool.Parse(dataFile.Data["public"]), true); if (dataFile.Data.ContainsKey("servername")) varSet("name", dataFile.Data["servername"], true); if (dataFile.Data.ContainsKey("sandbox")) varSet("sandbox", bool.Parse(dataFile.Data["sandbox"]), true); if (dataFile.Data.ContainsKey("notnt")) varSet("tnt", !bool.Parse(dataFile.Data["notnt"]), true); if (dataFile.Data.ContainsKey("sphericaltnt")) varSet("stnt", bool.Parse(dataFile.Data["sphericaltnt"]), true); if (dataFile.Data.ContainsKey("insanelava")) varSet("insanelava", bool.Parse(dataFile.Data["insanelava"]), true); if (dataFile.Data.ContainsKey("shockspreadslava")) varSet("sspreads", bool.Parse(dataFile.Data["shockspreadslava"]), true); if (dataFile.Data.ContainsKey("roadabsorbs")) varSet("roadabsorbs", bool.Parse(dataFile.Data["roadabsorbs"]), true); if (dataFile.Data.ContainsKey("minelava")) varSet("minelava", bool.Parse(dataFile.Data["minelava"]), true); if (dataFile.Data.ContainsKey("levelname")) levelToLoad = dataFile.Data["levelname"]; if (dataFile.Data.ContainsKey("greeter")) varSet("greeter", dataFile.Data["greeter"],true); bool autoannounce = true; if (dataFile.Data.ContainsKey("autoannounce")) autoannounce = bool.Parse(dataFile.Data["autoannounce"]); // Load the ban-list. banList = LoadBanList(); // Load the admin-list admins = LoadAdminList(); if (tmpMaxPlayers>=0) varSet("maxplayers", tmpMaxPlayers, true); // Initialize the server. NetConfiguration netConfig = new NetConfiguration("InfiniminerPlus"); netConfig.MaxConnections = (int)varGetI("maxplayers"); netConfig.Port = 5565; netServer = new InfiniminerNetServer(netConfig); netServer.SetMessageTypeEnabled(NetMessageType.ConnectionApproval, true); //netServer.SimulatedMinimumLatency = 0.1f; //netServer.SimulatedLatencyVariance = 0.05f; //netServer.SimulatedLoss = 0.1f; //netServer.SimulatedDuplicates = 0.05f; netServer.Start(); // Store the last time that we did a flow calculation. DateTime lastFlowCalc = DateTime.Now; DateTime lastMapeaterCalc = DateTime.Now; //Check if we should autoload a level if (dataFile.Data.ContainsKey("autoload") && bool.Parse(dataFile.Data["autoload"])) { blockList = new BlockType[MAPSIZE, MAPSIZE, MAPSIZE]; blockCreatorTeam = new PlayerTeam[MAPSIZE, MAPSIZE, MAPSIZE]; LoadLevel(levelToLoad); } else { // Calculate initial lava flows. ConsoleWrite("CALCULATING INITIAL LAVA FLOWS"); ConsoleWrite("TOTAL LAVA BLOCKS = " + newMap()); } //Caculate the shape of spherical tnt explosions CalculateExplosionPattern(); // Send the initial server list update. if (autoannounce) PublicServerListUpdate(true); lastMapBackup = DateTime.Now; ServerListener listener = new ServerListener(netServer,this); System.Threading.Thread listenerthread = new System.Threading.Thread(new ThreadStart(listener.start)); listenerthread.Start(); // Main server loop! ConsoleWrite("SERVER READY"); Random randomizer = new Random(56235676); while (keepRunning) { // Process any messages that are here. //Time to backup map? TimeSpan mapUpdateTimeSpan = DateTime.Now - lastMapBackup; if (mapUpdateTimeSpan.TotalMinutes > 5) { System.Threading.Thread backupthread = new System.Threading.Thread(new ThreadStart(BackupLevel)); backupthread.Start(); lastMapBackup = DateTime.Now; } // Time to send a new server update? PublicServerListUpdate(); //It checks for public server / time span //Time to terminate finished map sending threads? TerminateFinishedThreads(); // Check for players who are in the zone to deposit. DepositForPlayers(); // Is it time to do a lava calculation? If so, do it! if (varGetB("mapeater")) { TimeSpan eaterSpan = DateTime.Now - lastMapeaterCalc; if (eaterSpan.TotalMilliseconds > 500) { lastMapeaterCalc = DateTime.Now; for (int i = 0; i < 200; i++) { ushort x = (ushort)randomizer.Next(0, 64); ushort y = (ushort)randomizer.Next(0, 64); for (ushort z = 62; z > 0; z--) { if (blockList[x, z, y] != BlockType.None) { SetBlock(x, z, y, BlockType.None, PlayerTeam.None); break; } } } } } TimeSpan timeSpan = DateTime.Now - lastFlowCalc; if (timeSpan.TotalMilliseconds > 500) { DoLavaStuff(); lastFlowCalc = DateTime.Now; } // Handle console keypresses. while (Console.KeyAvailable) { ConsoleKeyInfo keyInfo = Console.ReadKey(); if (keyInfo.Key == ConsoleKey.Enter) ConsoleProcessInput(); else if (keyInfo.Key == ConsoleKey.Backspace) { if (consoleInput.Length > 0) consoleInput = consoleInput.Substring(0, consoleInput.Length - 1); ConsoleRedraw(); } else { consoleInput += keyInfo.KeyChar; ConsoleRedraw(); } } // Is the game over? if (winningTeam != PlayerTeam.None && !restartTriggered) { BroadcastGameOver(); restartTriggered = true; restartTime = DateTime.Now.AddSeconds(10); } // Restart the server? if (restartTriggered && DateTime.Now > restartTime) { SaveLevel("autosave_" + (UInt64)DateTime.Now.ToBinary() + ".lvl"); netServer.Shutdown("The server is restarting."); return true; } // Pass control over to waiting threads. Thread.Sleep(1); } MessageAll("Server going down NOW!"); netServer.Shutdown("The server was terminated."); return false; }
public bool Start() { //Setup the variable toggles varBindingsInitialize(); int tmpMaxPlayers = 16; // Read in from the config file. DatafileWriter dataFile = new DatafileWriter("server.config.txt"); if (dataFile.Data.ContainsKey("winningcash")) winningCashAmount = uint.Parse(dataFile.Data["winningcash"], System.Globalization.CultureInfo.InvariantCulture); if (dataFile.Data.ContainsKey("includelava")) includeLava = bool.Parse(dataFile.Data["includelava"]); if (dataFile.Data.ContainsKey("includewater")) includeLava = bool.Parse(dataFile.Data["includewater"]); if (dataFile.Data.ContainsKey("orefactor")) oreFactor = uint.Parse(dataFile.Data["orefactor"], System.Globalization.CultureInfo.InvariantCulture); if (dataFile.Data.ContainsKey("maxplayers")) tmpMaxPlayers = (int)Math.Min(32, uint.Parse(dataFile.Data["maxplayers"], System.Globalization.CultureInfo.InvariantCulture)); if (dataFile.Data.ContainsKey("public")) varSet("public", bool.Parse(dataFile.Data["public"]), true); if (dataFile.Data.ContainsKey("servername")) varSet("name", dataFile.Data["servername"], true); if (dataFile.Data.ContainsKey("sandbox")) varSet("sandbox", bool.Parse(dataFile.Data["sandbox"]), true); if (dataFile.Data.ContainsKey("notnt")) varSet("tnt", !bool.Parse(dataFile.Data["notnt"]), true); if (dataFile.Data.ContainsKey("sphericaltnt")) varSet("stnt", bool.Parse(dataFile.Data["sphericaltnt"]), true); if (dataFile.Data.ContainsKey("insane")) varSet("insane", bool.Parse(dataFile.Data["insane"]), true); if (dataFile.Data.ContainsKey("roadabsorbs")) varSet("roadabsorbs", bool.Parse(dataFile.Data["roadabsorbs"]), true); if (dataFile.Data.ContainsKey("minelava")) varSet("minelava", bool.Parse(dataFile.Data["minelava"]), true); if (dataFile.Data.ContainsKey("levelname")) levelToLoad = dataFile.Data["levelname"]; if (dataFile.Data.ContainsKey("greeter")) varSet("greeter", dataFile.Data["greeter"],true); bool autoannounce = true; if (dataFile.Data.ContainsKey("autoannounce")) autoannounce = bool.Parse(dataFile.Data["autoannounce"]); // Load the ban-list. banList = LoadBanList(); // Load the admin-list admins = LoadAdminList(); if (tmpMaxPlayers>=0) varSet("maxplayers", tmpMaxPlayers, true); // Initialize the server. NetConfiguration netConfig = new NetConfiguration("InfiniminerPlus"); netConfig.MaxConnections = (int)varGetI("maxplayers"); netConfig.Port = 5565; netServer = new InfiniminerNetServer(netConfig); netServer.SetMessageTypeEnabled(NetMessageType.ConnectionApproval, true); //netServer.SimulatedMinimumLatency = 0.1f; //netServer.SimulatedLatencyVariance = 0.05f; //netServer.SimulatedLoss = 0.1f; //netServer.SimulatedDuplicates = 0.05f; //netServer.Configuration.SendBufferSize = 2048000; //netServer.Start();//starts too early // Initialize variables we'll use. NetBuffer msgBuffer = netServer.CreateBuffer(); NetMessageType msgType; NetConnection msgSender; // Store the last time that we did a flow calculation. DateTime lastFlowCalc = DateTime.Now; //Check if we should autoload a level if (dataFile.Data.ContainsKey("autoload") && bool.Parse(dataFile.Data["autoload"])) { blockList = new BlockType[MAPSIZE, MAPSIZE, MAPSIZE]; blockCreatorTeam = new PlayerTeam[MAPSIZE, MAPSIZE, MAPSIZE]; LoadLevel(levelToLoad); lavaBlockCount = 0; waterBlockCount = 0; for (ushort i = 0; i < MAPSIZE; i++) for (ushort j = 0; j < MAPSIZE; j++) for (ushort k = 0; k < MAPSIZE; k++) { if (blockList[i, j, k] == BlockType.Lava) { lavaBlockCount += 1; } else if (blockList[i, j, k] == BlockType.Water) { waterBlockCount += 1; } } ConsoleWrite(waterBlockCount + " water blocks, " + lavaBlockCount + " lava blocks."); } else { // Calculate initial lava flows. ConsoleWrite("CALCULATING INITIAL LIQUID BLOCKS"); newMap(); lavaBlockCount = 0; waterBlockCount = 0; for (ushort i = 0; i < MAPSIZE; i++) for (ushort j = 0; j < MAPSIZE; j++) for (ushort k = 0; k < MAPSIZE; k++) { if (blockList[i, j, k] == BlockType.Lava) { lavaBlockCount += 1; } else if (blockList[i, j, k] == BlockType.Water) { waterBlockCount += 1; } } ConsoleWrite(waterBlockCount + " water blocks, " + lavaBlockCount + " lava blocks."); } //Caculate the shape of spherical tnt explosions CalculateExplosionPattern(); // Send the initial server list update. if (autoannounce) PublicServerListUpdate(true); lastMapBackup = DateTime.Now; DateTime lastFPScheck = DateTime.Now; double frameRate = 0; // Main server loop! netServer.Start(); ConsoleWrite("SERVER READY"); if (!physics.IsAlive) { ConsoleWrite("Physics thread is limp."); } while (keepRunning) { if (!physics.IsAlive) { ConsoleWrite("Physics thread died."); // physics.Abort(); // physics.Join(); //physics.Start(); } frameCount = frameCount + 1; if (lastFPScheck <= DateTime.Now - TimeSpan.FromMilliseconds(1000)) { lastFPScheck = DateTime.Now; frameRate = frameCount;// / gameTime.ElapsedTotalTime.TotalSeconds; if (sleeping == false && frameCount < 20) { ConsoleWrite("Heavy load: " + frameCount + " FPS"); } frameCount = 0; } // Process any messages that are here. while (netServer.ReadMessage(msgBuffer, out msgType, out msgSender)) { try { switch (msgType) { case NetMessageType.ConnectionApproval: { Player newPlayer = new Player(msgSender, null); newPlayer.Handle = Defines.Sanitize(msgBuffer.ReadString()).Trim(); if (newPlayer.Handle.Length == 0) { newPlayer.Handle = "Player"; } string clientVersion = msgBuffer.ReadString(); if (clientVersion != Defines.INFINIMINER_VERSION) { msgSender.Disapprove("VER;" + Defines.INFINIMINER_VERSION); } else if (banList.Contains(newPlayer.IP)) { msgSender.Disapprove("BAN;"); }/* else if (playerList.Count == maxPlayers) { msgSender.Disapprove("FULL;"); }*/ else { if (admins.ContainsKey(newPlayer.IP)) newPlayer.admin = admins[newPlayer.IP]; playerList[msgSender] = newPlayer; //Check if we should compress the map for the client try { bool compression = msgBuffer.ReadBoolean(); if (compression) playerList[msgSender].compression = true; } catch { } toGreet.Add(msgSender); this.netServer.SanityCheck(msgSender); msgSender.Approve(); PublicServerListUpdate(true); } } break; case NetMessageType.StatusChanged: { if (!this.playerList.ContainsKey(msgSender)) { break; } Player player = playerList[msgSender]; if (msgSender.Status == NetConnectionStatus.Connected) { if (sleeping == true) { sleeping = false; physicsEnabled = true; } ConsoleWrite("CONNECT: " + playerList[msgSender].Handle + " ( " + playerList[msgSender].IP + " )"); SendCurrentMap(msgSender); SendPlayerJoined(player); PublicServerListUpdate(); } else if (msgSender.Status == NetConnectionStatus.Disconnected) { ConsoleWrite("DISCONNECT: " + playerList[msgSender].Handle); SendPlayerLeft(player, player.Kicked ? "WAS KICKED FROM THE GAME!" : "HAS ABANDONED THEIR DUTIES!"); if (playerList.ContainsKey(msgSender)) playerList.Remove(msgSender); sleeping = true; foreach (Player p in playerList.Values) { sleeping = false; } if (sleeping == true) { ConsoleWrite("HIBERNATING"); physicsEnabled = false; } PublicServerListUpdate(); } } break; case NetMessageType.Data: { if (!this.playerList.ContainsKey(msgSender)) { break; } Player player = playerList[msgSender]; InfiniminerMessage dataType = (InfiniminerMessage)msgBuffer.ReadByte(); switch (dataType) { case InfiniminerMessage.ChatMessage: { // Read the data from the packet. ChatMessageType chatType = (ChatMessageType)msgBuffer.ReadByte(); string chatString = Defines.Sanitize(msgBuffer.ReadString()); if (!ProcessCommand(chatString,GetAdmin(playerList[msgSender].IP),playerList[msgSender])) { ConsoleWrite("CHAT: (" + player.Handle + ") " + chatString); // Append identifier information. if (chatType == ChatMessageType.SayAll) chatString = player.Handle + " (ALL): " + chatString; else chatString = player.Handle + " (TEAM): " + chatString; // Construct the message packet. NetBuffer chatPacket = netServer.CreateBuffer(); chatPacket.Write((byte)InfiniminerMessage.ChatMessage); chatPacket.Write((byte)((player.Team == PlayerTeam.Red) ? ChatMessageType.SayRedTeam : ChatMessageType.SayBlueTeam)); chatPacket.Write(chatString); // Send the packet to people who should recieve it. foreach (Player p in playerList.Values) { if (chatType == ChatMessageType.SayAll || chatType == ChatMessageType.SayBlueTeam && p.Team == PlayerTeam.Blue || chatType == ChatMessageType.SayRedTeam && p.Team == PlayerTeam.Red) if (p.NetConn.Status == NetConnectionStatus.Connected) netServer.SendMessage(chatPacket, p.NetConn, NetChannel.ReliableInOrder3); } } } break; case InfiniminerMessage.UseTool: { Vector3 playerPosition = msgBuffer.ReadVector3(); Vector3 playerHeading = msgBuffer.ReadVector3(); PlayerTools playerTool = (PlayerTools)msgBuffer.ReadByte(); BlockType blockType = (BlockType)msgBuffer.ReadByte(); switch (playerTool) { case PlayerTools.Pickaxe: UsePickaxe(player, playerPosition, playerHeading); break; case PlayerTools.ConstructionGun: UseConstructionGun(player, playerPosition, playerHeading, blockType); break; case PlayerTools.DeconstructionGun: UseDeconstructionGun(player, playerPosition, playerHeading); break; case PlayerTools.ProspectingRadar: UseSignPainter(player, playerPosition, playerHeading); break; case PlayerTools.Detonator: UseDetonator(player); break; case PlayerTools.SpawnItem: SpawnItem(player, playerPosition, playerHeading); break; } } break; case InfiniminerMessage.SelectClass: { PlayerClass playerClass = (PlayerClass)msgBuffer.ReadByte(); player.Alive = false; ConsoleWrite("SELECT_CLASS: " + player.Handle + ", " + playerClass.ToString()); switch (playerClass) { case PlayerClass.Engineer://strong arm/throws blocks player.OreMax = 350; player.WeightMax = 4; player.HealthMax = 400; player.Health = player.HealthMax; break; case PlayerClass.Miner: player.OreMax = 200; player.WeightMax = 8; player.HealthMax = 400; player.Health = player.HealthMax; break; case PlayerClass.Prospector: player.OreMax = 200; player.WeightMax = 4; player.HealthMax = 400; player.Health = player.HealthMax; break; case PlayerClass.Sapper: player.OreMax = 200; player.WeightMax = 4; player.HealthMax = 400; player.Health = player.HealthMax; break; } SendResourceUpdate(player); } break; case InfiniminerMessage.PlayerSetTeam: { PlayerTeam playerTeam = (PlayerTeam)msgBuffer.ReadByte(); ConsoleWrite("SELECT_TEAM: " + player.Handle + ", " + playerTeam.ToString()); player.Team = playerTeam; player.Health = 0; player.Alive = false; SendResourceUpdate(player); SendPlayerSetTeam(player); } break; case InfiniminerMessage.PlayerDead: { ConsoleWrite("PLAYER_DEAD: " + player.Handle); player.Ore = 0; player.Cash = 0; player.Weight = 0; player.Health = 0; player.Alive = false; SendResourceUpdate(player); SendPlayerDead(player); string deathMessage = msgBuffer.ReadString(); if (deathMessage != "") { msgBuffer = netServer.CreateBuffer(); msgBuffer.Write((byte)InfiniminerMessage.ChatMessage); msgBuffer.Write((byte)(player.Team == PlayerTeam.Red ? ChatMessageType.SayRedTeam : ChatMessageType.SayBlueTeam)); msgBuffer.Write(player.Handle + " " + deathMessage); foreach (NetConnection netConn in playerList.Keys) if (netConn.Status == NetConnectionStatus.Connected) netServer.SendMessage(msgBuffer, netConn, NetChannel.ReliableInOrder3); } SendPlayerRespawn(player);//allow this player to instantly respawn } break; case InfiniminerMessage.PlayerAlive: { if (toGreet.Contains(msgSender)) { string greeting = varGetS("greeter"); greeting = greeting.Replace("[name]", playerList[msgSender].Handle); if (greeting != "") { NetBuffer greetBuffer = netServer.CreateBuffer(); greetBuffer.Write((byte)InfiniminerMessage.ChatMessage); greetBuffer.Write((byte)ChatMessageType.SayAll); greetBuffer.Write(Defines.Sanitize(greeting)); netServer.SendMessage(greetBuffer, msgSender, NetChannel.ReliableInOrder3); } toGreet.Remove(msgSender); } ConsoleWrite("PLAYER_ALIVE: " + player.Handle); player.Ore = 0; player.Cash = 0; player.Weight = 0; player.Health = player.HealthMax; player.Alive = true; SendResourceUpdate(player); SendPlayerAlive(player); } break; case InfiniminerMessage.PlayerRespawn: { SendPlayerRespawn(player);//new respawn } break; case InfiniminerMessage.PlayerUpdate: { player.Position = Auth_Position(msgBuffer.ReadVector3(),player); player.Heading = Auth_Heading(msgBuffer.ReadVector3()); player.Tool = (PlayerTools)msgBuffer.ReadByte(); player.UsingTool = msgBuffer.ReadBoolean(); SendPlayerUpdate(player); } break; case InfiniminerMessage.PlayerUpdate1://minus position { player.Heading = Auth_Heading(msgBuffer.ReadVector3()); player.Tool = (PlayerTools)msgBuffer.ReadByte(); player.UsingTool = msgBuffer.ReadBoolean(); SendPlayerUpdate(player); } break; case InfiniminerMessage.PlayerUpdate2://minus position and heading { player.Tool = (PlayerTools)msgBuffer.ReadByte(); player.UsingTool = msgBuffer.ReadBoolean(); SendPlayerUpdate(player); } break; case InfiniminerMessage.PlayerHurt://client speaks of fall damage { uint newhp = msgBuffer.ReadUInt32(); if (newhp < player.Health) { player.Health = newhp; if (player.Health < 1) { player.Ore = 0;//should be calling death function for player player.Cash = 0; player.Weight = 0; player.Health = 0; player.Alive = false; SendResourceUpdate(player); SendPlayerDead(player); } } } break; case InfiniminerMessage.PlayerPosition://server not interested in clients complaints about position { } break; case InfiniminerMessage.PlayerInteract://client speaks of mashing on block { player.Position = Auth_Position(msgBuffer.ReadVector3(), player); uint btn = msgBuffer.ReadUInt32(); uint btnx = msgBuffer.ReadUInt32(); uint btny = msgBuffer.ReadUInt32(); uint btnz = msgBuffer.ReadUInt32(); if (blockList[btnx, btny, btnz] == BlockType.Pump || blockList[btnx, btny, btnz] == BlockType.Pipe || blockList[btnx, btny, btnz] == BlockType.Generator || blockList[btnx, btny, btnz] == BlockType.Compressor) { if (Get3DDistance((int)btnx, (int)btny, (int)btnz, (int)player.Position.X, (int)player.Position.Y, (int)player.Position.Z) < 4) { PlayerInteract(player,btn, btnx, btny, btnz); } } } break; case InfiniminerMessage.DepositOre: { DepositOre(player); foreach (Player p in playerList.Values) SendResourceUpdate(p); } break; case InfiniminerMessage.WithdrawOre: { WithdrawOre(player); foreach (Player p in playerList.Values) SendResourceUpdate(p); } break; case InfiniminerMessage.PlayerPing: { SendPlayerPing((uint)msgBuffer.ReadInt32()); } break; case InfiniminerMessage.PlaySound: { InfiniminerSound sound = (InfiniminerSound)msgBuffer.ReadByte(); Vector3 position = msgBuffer.ReadVector3(); PlaySound(sound, position); } break; case InfiniminerMessage.GetItem: { //verify players position before get player.Position = Auth_Position(msgBuffer.ReadVector3(), player); GetItem(player,msgBuffer.ReadString()); } break; } } break; } } catch { } } //Time to backup map? TimeSpan mapUpdateTimeSpan = DateTime.Now - lastMapBackup; if (mapUpdateTimeSpan.TotalMinutes > 5) { lastMapBackup = DateTime.Now; SaveLevel("autoBK.lvl"); } // Time to send a new server update? PublicServerListUpdate(); //It checks for public server / time span //Time to terminate finished map sending threads? TerminateFinishedThreads(); // Check for players who are in the zone to deposit. DepositForPlayers(); // Is it time to do a lava calculation? If so, do it! TimeSpan timeSpan = DateTime.Now - lastFlowCalc; if (timeSpan.TotalMilliseconds > 250)//needs separate timer for each substance { lastFlowCalc = DateTime.Now; //secondflow += 1; //if (secondflow > 2)//every 2nd flow, remove the vacuum that prevent re-spread //{ // EraseVacuum(); // secondflow = 0; //} foreach (Player p in playerList.Values)//regeneration { if (p.Alive) if (p.Health >= p.HealthMax) { p.Health = p.HealthMax; } else { p.Health = p.Health + 1; SendResourceUpdate(p); } } //physics = new Thread(new ThreadStart(this.DoStuff)); //DoStuff(); } // Handle console keypresses. while (Console.KeyAvailable) { ConsoleKeyInfo keyInfo = Console.ReadKey(); if (keyInfo.Key == ConsoleKey.Enter) ConsoleProcessInput(); else if (keyInfo.Key == ConsoleKey.Backspace) { if (consoleInput.Length > 0) consoleInput = consoleInput.Substring(0, consoleInput.Length - 1); ConsoleRedraw(); } else { consoleInput += keyInfo.KeyChar; ConsoleRedraw(); } } // Is the game over? if (winningTeam != PlayerTeam.None && !restartTriggered) { BroadcastGameOver(); restartTriggered = true; restartTime = DateTime.Now.AddSeconds(10); } // Restart the server? if (restartTriggered && DateTime.Now > restartTime) { SaveLevel("autosave_" + (UInt64)DateTime.Now.ToBinary() + ".lvl"); netServer.Shutdown("The server is restarting."); Thread.Sleep(100); physics.Abort(); return true;//terminates server thread completely } // Pass control over to waiting threads. if(sleeping == true) { Thread.Sleep(50); } else { Thread.Sleep(1); } } MessageAll("Server going down NOW!"); netServer.Shutdown("The server was terminated."); return false; }