/// <summary> /// Handles the turret fire through JSON commands. /// </summary> /// <param name="command"></param> /// <param name="id">The ID of the OWNDER tank firing, not the projectile ID.</param> /// <param name="speed"></param> internal void FireTurret(ControlCommand command, long id) { // Only Fire if the Tank's cooldown is reset or if alive. if (command.fire == "none" || deadTanks.ContainsKey(id)) { return; } if (command.fire == "main") { if (tanks[id].fireCD.ElapsedMilliseconds < FIRE_COOLDOWN) { return; } else { tanks[id].fireCD.Restart(); } Projectile p = new Projectile(GetRandomID(), (int)id, false, tanks[id].location, tanks[id].GetAiming()); projectiles.Add(p.ID, p); } if (command.fire == "alt") { if (tanks[id].PowerupCount >= 1) { tanks[id].PowerupCount -= 1; Beam b = new Beam(GetRandomID(), (int)id, tanks[id].location, tanks[id].GetAiming()); beams.Add(b.ID, b); b.duration.Start(); } } }
/// <summary> /// This method Set the given player's tank movement request /// This request is later processed when the seperate thread to update the /// world inside of server is called. /// </summary> /// <param name="command"></param> internal void SetMoveTank(ControlCommand command, long id) { // Dead tanks cant move lock (deadTanks) { if (deadTanks.ContainsKey(id)) { return; } } lock (tanks) { if (tanks[id].Collided == true) { tanks[id].tempLocation = tanks[id].location; } else { // Keep the temp. location updated instead of at (0, 0) tanks[id].tempLocation = tanks[id].location; tanks[id].Collided = false; } tanks[id].SetMoveRequest(command.moving); } }
/// <summary> /// Callback for ReceivePlayerName to handle incoming requests. /// Parses the JSON requests. This method uses the same logic as ClientSide handshake /// of Processing Messages, but instead of loading in objects we use the given information to /// update our tank with the ControlCommand. For incorrect commands that did not parse, we /// ignore the request. /// </summary> /// <param name="state"></param> private void HandleRequests(SocketState state) { if (state.ErrorOccured) { lock (serverWorld) { RemoveClient(state.ID); serverWorld.GetTank(state.ID).disconnected = true; return; } } lock (state) { string totalData = state.GetData(); string[] parts = Regex.Split(totalData, @"(?<=[\n])"); // Loop until we have processed all messages. foreach (string p in parts) { // Ignore empty strings added by the regex splitter if (p.Length == 0) { continue; } // Ignoring strings with no newline if (p[p.Length - 1] != '\n') { break; } // Skipping incomplete JSONS if (p[0] != '{' || !p.EndsWith("\n")) { continue; } // Process the command, update the tank w/ this client ID try { ControlCommand command = JsonConvert.DeserializeObject <ControlCommand>(p); serverWorld.SetMoveTank(command, state.ID); serverWorld.RotateTurret(command, state.ID); serverWorld.FireTurret(command, state.ID); } catch { /*command did not parse correctly; ignore*/ } //Remove data from the SocketState's growable buffer state.RemoveData(0, p.Length); } Networking.GetData(state); } }
private static void AddCommand(string name, string description, Func <IBootstrap, string[], bool> handler) { ControlCommand controlCommand = new ControlCommand() { Name = name, Description = description, Handler = handler }; Program.m_CommandHandlers.Add(controlCommand.Name, controlCommand); }
/// <summary> /// Handles the turret rotation through JSON commands. /// </summary> /// <param name="command"></param> /// <param name="iD"></param> internal void RotateTurret(ControlCommand command, long iD) { tanks[iD].SetAiming(command.tdir); }