private void UpdatePlayerPos(ServerClient c, byte[] rawdata) { var data = Functions.GetData(rawdata); c.Hero.Position.X = (float)data[0]; c.Hero.Position.Y = (float)data[1]; RelayMessage(c, rawdata, RelaySwitch.Room); }
private void ProcessMessage(Message msg, ServerClient c) { byte[] data = msg.Data; byte header = data[0]; if (Debug.DebugMode && data[0] != MsgHeader.PlayerPos) PrintMsg(data); switch (header) { case MsgHeader.Null: break; case MsgHeader.ClientReady: InitNewPlayer(c, data); break; case MsgHeader.PlayerPos: UpdatePlayerPos(c, data); break; case MsgHeader.Chat: RelayMessage(c, data, RelaySwitch.All); break; case MsgHeader.Quit: //tell everyone in the room to disconnect foreach (var c1 in c.Room.Clients.Where(c2 => c2 != c)) c1.SendRemovePlayer(c); break; default: throw new ArgumentException("Unhandled message received by server"); } }
private Mob() { MovingSpeed = 6; Removed = false; Netid = 0; State = MobState.Roaming; SenseDistance = 8; AttackDistance = 2; AttackSpeed = TimeSpan.FromSeconds(2); HeroTarget = null; ShapeManager.AddCircle(this); }
/// <summary> /// Appends netid and resend to everyone else than c /// </summary> /// <param name="c">who was sender originally</param> /// <param name="rawdata">this is 'data' array from 'Server.ProcessMessage()'</param> private void RelayMessage(ServerClient c, byte[] rawdata, RelaySwitch rswitch) { //+6 means 1 byte in the fron for len, 1 byte in the back for format and very last 4 bytes for int byte[] relaymsg = new byte[rawdata.Length + 6]; //new length relaymsg[0] = (byte)(rawdata.Length + 5); Array.Copy(rawdata, 0, relaymsg, 1, rawdata.Length); //add netid relaymsg[rawdata.Length + 1] = (byte)'i'; Array.Copy(c.zNetidBytes, 0, relaymsg, rawdata.Length + 2, 4); //resend if (rswitch == RelaySwitch.Room) { foreach( ServerClient c1 in c.Room.Clients.Where(c2=>c2 != c)) c1.zSendMessage(relaymsg); } else { foreach (MapRoom r in Rooms.Values) foreach (ServerClient client in r.Clients.Where(p => p != c)) client.zSendMessage(relaymsg); } }
public void SendRemovePlayer(ServerClient c) { SendMessage(MsgHeader.RemovePlayer, c.Hero.Netid); }
/// <summary> /// Sends newly connected client data about players, monsters and items on the ground /// </summary> /// <param name="c"></param> private void InitNewPlayer(ServerClient client, byte[] rawData) { var data = Functions.GetData(rawData); client.Hero.Name = data[0] as string; client.Hero.Class = (HeroClass)Convert.ToChar(data[1]); MobMap heroMap = (MobMap)Convert.ToChar(data[2]); TransferClient(client, heroMap); client.Hero.Position = new Vector3(0, 0, 0); //tell old players about new player and new player about old players foreach (var c in client.Room.Clients.Where(c1 => c1 != client)) { client.SendAddPlayer(c.Hero); c.SendAddPlayer(client.Hero); } //send mob data foreach (Mob m in client.Room.Mobs) client.SendNewMob(m); }
private void TransferClient(ServerClient c, MobMap dst) { ClientMutex.WaitOne(); c.Room.Clients.Remove(c); c.Room = Rooms[dst]; Rooms[dst].Clients.Add(c); ClientMutex.ReleaseMutex(); }
/// <summary> /// Returns and removes /// </summary> /// <param name="c"></param> /// <returns></returns> private Message DequeueMessage(ServerClient c) => c.mDequeueMessage();
/// <summary> /// Thread that accepts clients /// </summary> void AcceptClients() { try { while (true) { var newSocket = Socket.AcceptTcpClient(); var newClient = new ServerClient(newSocket); newClient.zId = GetNextId(); newClient.zNetidBytes = BitConverter.GetBytes(newClient.zId); newClient.Hero.Netid = newClient.Id; newClient.ReceiveThread.Start(); //by default, everyone starts in lorencia, relocation occurs when client sends ready //message with correct room id ClientMutex.WaitOne(); Rooms[MobMap.Lorencia].Clients.Add(newClient); ClientMutex.ReleaseMutex(); newClient.Room = Rooms[MobMap.Lorencia]; //send welcome msg newClient.SendMessage(MsgHeader.Welcome); } } catch (SocketException se) { if (se.ErrorCode == 10004 && State == ServerState.Stopped) { } else throw se; } }
public void RemoveAndDcClient(ServerClient c) { Debug.Write($"{c.IP} disconnected"); foreach (var c1 in c.Room.Clients.Where(c2 => c2 != c)) c1.SendRemovePlayer(c); c.Socket.Close(); ClientMutex.WaitOne(); c.Room.Clients.Remove(c); ClientMutex.ReleaseMutex(); }
private void ClientActivity(ServerClient c) { var msg = DequeueMessage(c); if (msg != null) { ProcessMessage(msg, c); Download += msg.Data.Length + 1; } if (c.ReceiveThread.ThreadState == ThreadState.Stopped) { ClientMutex.WaitOne(); RemoveAndDcClient(c); ClientMutex.ReleaseMutex(); } }
private void ServerRoaming() { //find target thats close enough ServerClient target = Room.Clients.FirstOrDefault(c => (Position - c.Hero.Position).LengthSquared() < SenseDistance * SenseDistance); if (target != null) { State = MobState.Chasing; HeroTarget = target; } }
private void ServerChasing() { Target = HeroTarget.Hero.Position; //stop chasing if it's too far if (HeroTarget == null || (Position - HeroTarget.Hero.Position).LengthSquared() > SenseDistance * SenseDistance) { State = MobState.Roaming; HeroTarget = null; return; } //start attacking if it's close enough else if ((Position - HeroTarget.Hero.Position).LengthSquared() < AttackDistance * AttackDistance) { State = MobState.Atacking; Target = Position; Globals.EventManager.AddEvent(AttackHero, $"attacking{Netid}", false, TimeSpan.Zero, TimeSpan.Zero, AttackSpeed); } }