├── .gitignore ├── .vs └── SlitherNET │ └── v14 │ └── .suo ├── README.md ├── SlitherNET.sln ├── SlitherNET ├── App.config ├── Game │ ├── Food.cs │ ├── GameRoom.cs │ ├── Snake.cs │ ├── SnakePart.cs │ └── Vector2f.cs ├── Metadata.cs ├── Network │ ├── BigEndianReader.cs │ ├── BigEndianWriter.cs │ ├── GameClient.cs │ └── Packets │ │ ├── Client │ │ ├── CMSG_SetUsername.cs │ │ └── CMSG_Update.cs │ │ ├── IPacket.cs │ │ └── Server │ │ ├── SMSG_F_MapFoods.cs │ │ ├── SMSG_G_UpdateSnake.cs │ │ ├── SMSG_a_InitialPacket.cs │ │ ├── SMSG_e_UpdateSnakeDirection.cs │ │ ├── SMSG_l_Leaderboard.cs │ │ ├── SMSG_m_MessageOfTheDay.cs │ │ ├── SMSG_p_Pong.cs │ │ └── SMSG_s_NewSnake.cs ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── Research.txt ├── Settings.yaml ├── SlitherNET.csproj ├── bin │ └── Debug │ │ ├── Settings.yaml │ │ ├── SlitherNET.exe │ │ ├── SlitherNET.exe.config │ │ ├── SlitherNET.pdb │ │ ├── SlitherNET.vshost.exe │ │ ├── SlitherNET.vshost.exe.config │ │ ├── SlitherNET.vshost.exe.manifest │ │ ├── YamlDotNet.dll │ │ ├── YamlDotNet.pdb │ │ ├── YamlDotNet.xml │ │ ├── websocket-sharp.dll │ │ └── websocket-sharp.xml └── packages.config └── packages └── WebSocketSharp.1.0.3-rc9 ├── WebSocketSharp.1.0.3-rc9.nupkg └── lib ├── websocket-sharp.dll └── websocket-sharp.xml /.gitignore: -------------------------------------------------------------------------------- 1 | /SlitherNET/obj 2 | -------------------------------------------------------------------------------- /.vs/SlitherNET/v14/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nightwolf93/SlitherNET/42e48b08a5e870da62992431c01d063442f7a667/.vs/SlitherNET/v14/.suo -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SlitherNET 2 | A unofficially .net server for the game slither.io 3 | 4 | WIP Server, some crappy code here. 5 | Thanks to : @Kogs, @circa94, @ThunderGemios10 6 | -------------------------------------------------------------------------------- /SlitherNET.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlitherNET", "SlitherNET\SlitherNET.csproj", "{9E10E058-4316-4791-8F5C-5C66E768D9D8}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {9E10E058-4316-4791-8F5C-5C66E768D9D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {9E10E058-4316-4791-8F5C-5C66E768D9D8}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {9E10E058-4316-4791-8F5C-5C66E768D9D8}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {9E10E058-4316-4791-8F5C-5C66E768D9D8}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /SlitherNET/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SlitherNET/Game/Food.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SlitherNET.Game 8 | { 9 | public class Food 10 | { 11 | public Vector2f Position { get; set; } 12 | public byte Color { get; set; } 13 | 14 | public Food(Vector2f position, byte color) 15 | { 16 | this.Position = position; 17 | this.Color = color; 18 | } 19 | 20 | public Food(byte color) 21 | { 22 | this.Color = color; 23 | this.setRandomPosition(); 24 | } 25 | 26 | public Food() 27 | { 28 | this.Color = (byte)Metadata.Rng.Next(0, 23); 29 | this.setRandomPosition(); 30 | } 31 | 32 | private void setRandomPosition() 33 | { 34 | var randomX = Metadata.Rng.Next(22907, 30000); 35 | var randomY = Metadata.Rng.Next(19137, 30337); 36 | 37 | this.Position = new Vector2f(randomX, randomY); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /SlitherNET/Game/GameRoom.cs: -------------------------------------------------------------------------------- 1 | using SlitherNET.Network; 2 | using SlitherNET.Network.Packets.Server; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace SlitherNET.Game 10 | { 11 | public class GameRoom 12 | { 13 | public List Foods { get; set; } 14 | public List Players { get; set; } 15 | 16 | public GameRoom() 17 | { 18 | this.Foods = new List(); 19 | this.Players = new List(); 20 | this.initializeFoods(); 21 | } 22 | 23 | private void initializeFoods() 24 | { 25 | for (int i = 0; i < 10000; i++) 26 | { 27 | this.Foods.Add(new Food()); 28 | } 29 | } 30 | 31 | public void AddPlayer(GameClient session) 32 | { 33 | lock (this.Players) 34 | { 35 | this.Players.Add(session); 36 | } 37 | } 38 | 39 | public void RemovePlayer(GameClient session) 40 | { 41 | lock (this.Players) 42 | { 43 | this.Players.Remove(session); 44 | } 45 | } 46 | 47 | public void ShowFoods(GameClient session) 48 | { 49 | session.SendPacket(new SMSG_F_MapFoods(this.Foods)); 50 | } 51 | 52 | public void UpdateLeaderboard() 53 | { 54 | var snakes = new List(); 55 | foreach(var c in this.Players) 56 | { 57 | snakes.Add(c.MySnake); 58 | } 59 | foreach(var client in this.Players) 60 | { 61 | client.SendPacket(new SMSG_l_Leaderboard(1, snakes)); 62 | } 63 | } 64 | 65 | private static GameRoom mRoom { get; set; } 66 | public static GameRoom Instance 67 | { 68 | get 69 | { 70 | if (mRoom == null) mRoom = new GameRoom(); 71 | return mRoom; 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /SlitherNET/Game/Snake.cs: -------------------------------------------------------------------------------- 1 | using SlitherNET.Network; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Drawing; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace SlitherNET.Game 10 | { 11 | public class Snake 12 | { 13 | public int ID { get; set; } 14 | public float Speed { get; set; } 15 | public int Skin { get; set; } 16 | public Vector2f Position { get; set; } 17 | public string Name { get; set; } 18 | public Vector2f HeadPosition { get; set; } 19 | public List Parts { get; set; } 20 | public int Size { get; set; } 21 | public short CurrentAngle { get; set; } 22 | 23 | public GameClient Player { get; set; } 24 | 25 | public Snake() 26 | { 27 | this.Parts = new List(); 28 | for (int i = 0; i < 50; i += 2) 29 | { 30 | this.Parts.Add(new SnakePart(this, new Vector2f(i + 1, i + 2))); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SlitherNET/Game/SnakePart.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SlitherNET.Game 8 | { 9 | public class SnakePart 10 | { 11 | public Snake Body { get; set; } 12 | public Vector2f Position { get; set; } 13 | 14 | public SnakePart(Snake body, Vector2f position) 15 | { 16 | this.Body = body; 17 | this.Position = position; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SlitherNET/Game/Vector2f.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SlitherNET.Game 8 | { 9 | public class Vector2f 10 | { 11 | public float X { get; set; } 12 | public float Y { get; set; } 13 | 14 | public Vector2f(float x, float y) 15 | { 16 | this.X = x; 17 | this.Y = y; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SlitherNET/Metadata.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SlitherNET 8 | { 9 | public class Metadata 10 | { 11 | public const byte PROTOCOL_VERSION = 6; 12 | public static Random Rng = new Random(Environment.TickCount); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SlitherNET/Network/BigEndianReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | 7 | namespace SlitherNET.Network 8 | { 9 | public class BigEndianReader 10 | { 11 | #region Properties 12 | 13 | private BinaryReader m_reader; 14 | 15 | /// 16 | /// Gets availiable bytes number in the buffer 17 | /// 18 | public long BytesAvailable 19 | { 20 | get { return m_reader.BaseStream.Length - m_reader.BaseStream.Position; } 21 | } 22 | 23 | public long Position 24 | { 25 | get 26 | { 27 | return m_reader.BaseStream.Position; 28 | } 29 | } 30 | 31 | 32 | public Stream BaseStream 33 | { 34 | get 35 | { 36 | return m_reader.BaseStream; 37 | } 38 | } 39 | 40 | #endregion 41 | 42 | #region Initialisation 43 | 44 | /// 45 | /// Initializes a new instance of the class. 46 | /// 47 | public BigEndianReader() 48 | { 49 | m_reader = new BinaryReader(new MemoryStream(), Encoding.UTF8); 50 | } 51 | 52 | /// 53 | /// Initializes a new instance of the class. 54 | /// 55 | /// The stream. 56 | public BigEndianReader(Stream stream) 57 | { 58 | m_reader = new BinaryReader(stream, Encoding.UTF8); 59 | } 60 | 61 | /// 62 | /// Initializes a new instance of the class. 63 | /// 64 | /// Memory buffer. 65 | public BigEndianReader(byte[] tab) 66 | { 67 | m_reader = new BinaryReader(new MemoryStream(tab), Encoding.UTF8); 68 | } 69 | 70 | #endregion 71 | 72 | #region Private Methods 73 | 74 | /// 75 | /// Read bytes in big endian format 76 | /// 77 | /// 78 | /// 79 | private byte[] ReadBigEndianBytes(int count) 80 | { 81 | var bytes = new byte[count]; 82 | int i; 83 | for (i = count - 1; i >= 0; i--) 84 | bytes[i] = (byte)BaseStream.ReadByte(); 85 | return bytes; 86 | } 87 | 88 | #endregion 89 | 90 | #region Public Method 91 | 92 | /// 93 | /// Read a Short from the Buffer 94 | /// 95 | /// 96 | public short ReadShort() 97 | { 98 | return BitConverter.ToInt16(ReadBigEndianBytes(2), 0); 99 | } 100 | 101 | /// 102 | /// Read a int from the Buffer 103 | /// 104 | /// 105 | public int ReadInt() 106 | { 107 | return BitConverter.ToInt32(ReadBigEndianBytes(4), 0); 108 | } 109 | 110 | /// 111 | /// Read a long from the Buffer 112 | /// 113 | /// 114 | public Int64 ReadLong() 115 | { 116 | return BitConverter.ToInt64(ReadBigEndianBytes(8), 0); 117 | } 118 | 119 | /// 120 | /// Read a Float from the Buffer 121 | /// 122 | /// 123 | public float ReadFloat() 124 | { 125 | return BitConverter.ToSingle(ReadBigEndianBytes(4), 0); 126 | } 127 | 128 | /// 129 | /// Read a UShort from the Buffer 130 | /// 131 | /// 132 | public ushort ReadUShort() 133 | { 134 | return BitConverter.ToUInt16(ReadBigEndianBytes(2), 0); 135 | } 136 | 137 | /// 138 | /// Read a int from the Buffer 139 | /// 140 | /// 141 | public UInt32 ReadUInt() 142 | { 143 | return BitConverter.ToUInt32(ReadBigEndianBytes(4), 0); 144 | } 145 | 146 | /// 147 | /// Read a long from the Buffer 148 | /// 149 | /// 150 | public UInt64 ReadULong() 151 | { 152 | return BitConverter.ToUInt64(ReadBigEndianBytes(8), 0); 153 | } 154 | 155 | /// 156 | /// Read a byte from the Buffer 157 | /// 158 | /// 159 | public byte ReadByte() 160 | { 161 | return m_reader.ReadByte(); 162 | } 163 | 164 | public sbyte ReadSByte() 165 | { 166 | return m_reader.ReadSByte(); 167 | } 168 | 169 | /// 170 | /// Returns N bytes from the buffer 171 | /// 172 | /// Number of read bytes. 173 | /// 174 | public byte[] ReadBytes(int n) 175 | { 176 | return m_reader.ReadBytes(n); 177 | } 178 | 179 | /// 180 | /// Returns N bytes from the buffer 181 | /// 182 | /// Number of read bytes. 183 | /// 184 | public BigEndianReader ReadBytesInNewBigEndianReader(int n) 185 | { 186 | return new BigEndianReader(m_reader.ReadBytes(n)); 187 | } 188 | 189 | /// 190 | /// Read a Boolean from the Buffer 191 | /// 192 | /// 193 | public Boolean ReadBoolean() 194 | { 195 | return m_reader.ReadByte() == 1; 196 | } 197 | 198 | /// 199 | /// Read a Char from the Buffer 200 | /// 201 | /// 202 | public Char ReadChar() 203 | { 204 | return (char)ReadUShort(); 205 | } 206 | 207 | /// 208 | /// Read a Double from the Buffer 209 | /// 210 | /// 211 | public Double ReadDouble() 212 | { 213 | return BitConverter.ToDouble(ReadBigEndianBytes(8), 0); 214 | } 215 | 216 | /// 217 | /// Read a Single from the Buffer 218 | /// 219 | /// 220 | public Single ReadSingle() 221 | { 222 | return BitConverter.ToSingle(ReadBigEndianBytes(4), 0); 223 | } 224 | 225 | /// 226 | /// Read a string from the Buffer 227 | /// 228 | /// 229 | public string ReadUTF() 230 | { 231 | ushort length = ReadUShort(); 232 | 233 | byte[] bytes = ReadBytes(length); 234 | return Encoding.UTF8.GetString(bytes); 235 | } 236 | 237 | public string ReadString() 238 | { 239 | ushort length = ReadByte(); 240 | 241 | byte[] bytes = ReadBytes(length); 242 | return Encoding.UTF8.GetString(bytes); 243 | } 244 | 245 | public string ReadEndString() 246 | { 247 | byte[] bytes = ReadBytes((int)(this.BytesAvailable)); 248 | return Encoding.UTF8.GetString(bytes); 249 | } 250 | 251 | /// 252 | /// Read a string from the Buffer 253 | /// 254 | /// 255 | public string ReadUTF7BitLength() 256 | { 257 | int length = ReadInt(); 258 | 259 | byte[] bytes = ReadBytes(length); 260 | return Encoding.UTF8.GetString(bytes); 261 | } 262 | 263 | /// 264 | /// Read a string from the Buffer 265 | /// 266 | /// 267 | public string ReadUTFBytes(ushort len) 268 | { 269 | byte[] bytes = ReadBytes(len); 270 | 271 | return Encoding.UTF8.GetString(bytes); 272 | } 273 | 274 | /// 275 | /// Skip bytes 276 | /// 277 | /// 278 | public void SkipBytes(int n) 279 | { 280 | int i; 281 | for (i = 0; i < n; i++) 282 | { 283 | m_reader.ReadByte(); 284 | } 285 | } 286 | 287 | 288 | public void Seek(int offset, SeekOrigin seekOrigin) 289 | { 290 | m_reader.BaseStream.Seek(offset, seekOrigin); 291 | } 292 | 293 | /// 294 | /// Add a bytes array to the end of the buffer 295 | /// 296 | public void Add(byte[] data, int offset, int count) 297 | { 298 | long pos = m_reader.BaseStream.Position; 299 | 300 | m_reader.BaseStream.Position = m_reader.BaseStream.Length; 301 | m_reader.BaseStream.Write(data, offset, count); 302 | m_reader.BaseStream.Position = pos; 303 | } 304 | 305 | #endregion 306 | 307 | #region Dispose 308 | 309 | /// 310 | /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 311 | /// 312 | public void Dispose() 313 | { 314 | m_reader.Dispose(); 315 | m_reader = null; 316 | } 317 | 318 | #endregion 319 | } 320 | } 321 | -------------------------------------------------------------------------------- /SlitherNET/Network/BigEndianWriter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | 7 | namespace SlitherNET.Network 8 | { 9 | public class BigEndianWriter 10 | { 11 | #region Properties 12 | 13 | private BinaryWriter m_writer; 14 | 15 | public Stream BaseStream 16 | { 17 | get { return m_writer.BaseStream; } 18 | } 19 | 20 | public Dictionary Marks = new Dictionary(); 21 | 22 | /// 23 | /// Gets available bytes number in the buffer 24 | /// 25 | public long BytesAvailable 26 | { 27 | get { return m_writer.BaseStream.Length - m_writer.BaseStream.Position; } 28 | } 29 | 30 | public long Position 31 | { 32 | get { return m_writer.BaseStream.Position; } 33 | set 34 | { 35 | m_writer.BaseStream.Position = value; 36 | } 37 | } 38 | 39 | public byte[] Data 40 | { 41 | get 42 | { 43 | var pos = m_writer.BaseStream.Position; 44 | 45 | var data = new byte[m_writer.BaseStream.Length]; 46 | m_writer.BaseStream.Position = 0; 47 | m_writer.BaseStream.Read(data, 0, (int)m_writer.BaseStream.Length); 48 | 49 | m_writer.BaseStream.Position = pos; 50 | 51 | return data; 52 | } 53 | } 54 | 55 | #endregion 56 | 57 | #region Initialisation 58 | 59 | /// 60 | /// Initializes a new instance of the class. 61 | /// 62 | public BigEndianWriter() 63 | { 64 | m_writer = new BinaryWriter(new MemoryStream(), Encoding.UTF8); 65 | } 66 | 67 | /// 68 | /// Initializes a new instance of the class. 69 | /// 70 | /// The stream. 71 | public BigEndianWriter(Stream stream) 72 | { 73 | m_writer = new BinaryWriter(stream, Encoding.UTF8); 74 | } 75 | 76 | #endregion 77 | 78 | #region Private Methods 79 | 80 | /// 81 | /// Reverse bytes and write them into the buffer 82 | /// 83 | private void WriteBigEndianBytes(byte[] endianBytes) 84 | { 85 | for (int i = endianBytes.Length - 1; i >= 0; i--) 86 | { 87 | m_writer.Write(endianBytes[i]); 88 | } 89 | } 90 | 91 | #endregion 92 | 93 | #region Public Methods 94 | 95 | /// 96 | /// Write a Short into the buffer 97 | /// 98 | /// 99 | public void WriteShort(short @short) 100 | { 101 | WriteBigEndianBytes(BitConverter.GetBytes(@short)); 102 | } 103 | 104 | /// 105 | /// Write a int into the buffer 106 | /// 107 | /// 108 | public void WriteInt(int @int) 109 | { 110 | WriteBigEndianBytes(BitConverter.GetBytes(@int)); 111 | } 112 | 113 | /// 114 | /// Write a long into the buffer 115 | /// 116 | /// 117 | public void WriteLong(Int64 @long) 118 | { 119 | WriteBigEndianBytes(BitConverter.GetBytes(@long)); 120 | } 121 | 122 | /// 123 | /// Write a UShort into the buffer 124 | /// 125 | /// 126 | public void WriteUShort(ushort @ushort) 127 | { 128 | WriteBigEndianBytes(BitConverter.GetBytes(@ushort)); 129 | } 130 | 131 | /// 132 | /// Write a int into the buffer 133 | /// 134 | /// 135 | public void WriteUInt(UInt32 @uint) 136 | { 137 | WriteBigEndianBytes(BitConverter.GetBytes(@uint)); 138 | } 139 | 140 | /// 141 | /// Write a long into the buffer 142 | /// 143 | /// 144 | public void WriteULong(UInt64 @ulong) 145 | { 146 | WriteBigEndianBytes(BitConverter.GetBytes(@ulong)); 147 | } 148 | 149 | /// 150 | /// Write a byte into the buffer 151 | /// 152 | /// 153 | public void WriteByte(byte @byte) 154 | { 155 | m_writer.Write(@byte); 156 | } 157 | 158 | public void WriteInt24(double @int) 159 | { 160 | var number = (int)Math.Floor(@int); 161 | this.WriteByte((byte)(number >> 16)); 162 | this.WriteByte((byte)(number >> 8)); 163 | this.WriteByte((byte)(number & 0xFF)); 164 | } 165 | 166 | public void WriteSByte(sbyte @byte) 167 | { 168 | m_writer.Write(@byte); 169 | } 170 | /// 171 | /// Write a Float into the buffer 172 | /// 173 | /// 174 | public void WriteFloat(float @float) 175 | { 176 | m_writer.Write(@float); 177 | } 178 | 179 | /// 180 | /// Write a Boolean into the buffer 181 | /// 182 | /// 183 | public void WriteBoolean(Boolean @bool) 184 | { 185 | if (@bool) 186 | { 187 | m_writer.Write((byte)1); 188 | } 189 | else 190 | { 191 | m_writer.Write((byte)0); 192 | } 193 | } 194 | 195 | public void WriteBytesFromString(string bytes) 196 | { 197 | foreach (var b in bytes.Split(' ')) 198 | { 199 | if (b != "") 200 | { 201 | this.WriteBytes(Encoding.UTF8.GetBytes(b)); 202 | } 203 | } 204 | } 205 | 206 | /// 207 | /// Write a Char into the buffer 208 | /// 209 | /// 210 | public void WriteChar(Char @char) 211 | { 212 | WriteBigEndianBytes(BitConverter.GetBytes(@char)); 213 | } 214 | 215 | /// 216 | /// Write a Double into the buffer 217 | /// 218 | public void WriteDouble(Double @double) 219 | { 220 | WriteBigEndianBytes(BitConverter.GetBytes(@double)); 221 | } 222 | 223 | /// 224 | /// Write a Single into the buffer 225 | /// 226 | /// 227 | public void WriteSingle(Single @single) 228 | { 229 | WriteBigEndianBytes(BitConverter.GetBytes(@single)); 230 | } 231 | 232 | /// 233 | /// Write a string into the buffer 234 | /// 235 | /// 236 | public void WriteUTF(string str) 237 | { 238 | var bytes = Encoding.UTF8.GetBytes(str); 239 | var len = (ushort)bytes.Length; 240 | WriteUShort(len); 241 | 242 | int i; 243 | for (i = 0; i < len; i++) 244 | m_writer.Write(bytes[i]); 245 | } 246 | 247 | public void WriteString(string str) 248 | { 249 | var bytes = Encoding.UTF8.GetBytes(str); 250 | var len = (byte)bytes.Length; 251 | WriteByte(len); 252 | 253 | int i; 254 | for (i = 0; i < len; i++) 255 | WriteByte(bytes[i]); 256 | } 257 | 258 | public void WriteBigString(string str) 259 | { 260 | var bytes = Encoding.UTF8.GetBytes(str); 261 | var len = (byte)bytes.Length; 262 | WriteShort(len); 263 | 264 | int i; 265 | for (i = 0; i < len; i++) 266 | m_writer.Write(bytes[i]); 267 | } 268 | 269 | /// 270 | /// Write a string into the buffer 271 | /// 272 | /// 273 | public void WriteUTFBytes(string str) 274 | { 275 | var bytes = Encoding.UTF8.GetBytes(str); 276 | var len = bytes.Length; 277 | int i; 278 | for (i = 0; i < len; i++) 279 | m_writer.Write(bytes[i]); 280 | } 281 | 282 | /// 283 | /// Write a bytes array into the buffer 284 | /// 285 | /// 286 | public void WriteBytes(byte[] data) 287 | { 288 | m_writer.Write(data); 289 | } 290 | 291 | public void Seek(int offset, SeekOrigin seekOrigin) 292 | { 293 | m_writer.BaseStream.Seek(offset, seekOrigin); 294 | } 295 | 296 | public void Clear() 297 | { 298 | m_writer = new BinaryWriter(new MemoryStream(), Encoding.UTF8); 299 | } 300 | 301 | #endregion 302 | 303 | #region Marks System 304 | 305 | public void MarkShort(int index) 306 | { 307 | this.Marks.Add(index, this.Position); 308 | this.WriteShort(0); 309 | } 310 | 311 | public void EndMarkShort(int index, int add = 0) 312 | { 313 | var mark = this.Marks[index]; 314 | var pos = this.Position; 315 | this.Position = mark; 316 | this.WriteShort((short)(pos - (mark - add))); 317 | this.Seek(0, SeekOrigin.End); 318 | } 319 | 320 | #endregion 321 | 322 | #region Dispose 323 | 324 | public void Dispose() 325 | { 326 | m_writer.Dispose(); 327 | m_writer = null; 328 | } 329 | 330 | #endregion 331 | } 332 | } 333 | -------------------------------------------------------------------------------- /SlitherNET/Network/GameClient.cs: -------------------------------------------------------------------------------- 1 | using SlitherNET.Game; 2 | using SlitherNET.Network; 3 | using SlitherNET.Network.Packets; 4 | using SlitherNET.Network.Packets.Client; 5 | using SlitherNET.Network.Packets.Server; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.IO; 9 | using System.Linq; 10 | using System.Runtime.InteropServices; 11 | using System.Text; 12 | using System.Threading.Tasks; 13 | using System.Timers; 14 | using WebSocketSharp; 15 | using WebSocketSharp.Server; 16 | 17 | namespace SlitherNET.Network 18 | { 19 | public class GameClient : WebSocketBehavior 20 | { 21 | public int GameState = 1; 22 | public string Username = string.Empty; 23 | public Snake MySnake = null; 24 | public bool Active = true; 25 | public Timer LogicTimer { get; set; } 26 | 27 | protected override void OnClose(CloseEventArgs e) 28 | { 29 | Console.WriteLine("Connection closed with the player"); 30 | this.Active = false; 31 | GameRoom.Instance.RemovePlayer(this); 32 | GameRoom.Instance.UpdateLeaderboard(); 33 | base.OnClose(e); 34 | } 35 | 36 | protected override void OnMessage(MessageEventArgs e) 37 | { 38 | Console.WriteLine("Received message (LEN : " + e.RawData.Length + ")"); 39 | 40 | if (GameState == 1) // Username 41 | { 42 | // Set the username 43 | var usernamePacket = new CMSG_SetUsername(); 44 | usernamePacket.Deserialize(e.RawData); 45 | this.Username = usernamePacket.Username; 46 | 47 | // Send the initial packet 48 | this.GameState = 2; 49 | this.SendPacket(new SMSG_a_InitialPacket(21600)); 50 | 51 | this.MySnake = new Snake() 52 | { 53 | Player = this, 54 | ID = 1, 55 | Speed = (float)(5.76 * 1E3), 56 | Skin = usernamePacket.SkinId, 57 | Position = new Vector2f((float)(28907.6 * 5), (float)(21137.4 * 5)), 58 | Name = this.Username == "" ? "Anonymous" : this.Username, 59 | HeadPosition = new Vector2f(28907.3f * 5, 21136.8f * 5), 60 | }; 61 | this.SendPacket(new SMSG_s_NewSnake(this.MySnake)); 62 | this.SendPacket(new SMSG_m_MessageOfTheDay(Program.Settings.Basic.Motd, Program.Settings.Basic.Caption)); 63 | 64 | GameRoom.Instance.AddPlayer(this); 65 | GameRoom.Instance.ShowFoods(this); 66 | GameRoom.Instance.UpdateLeaderboard(); 67 | this.SendPacket(new SMSG_p_Pong()); 68 | 69 | this.LogicTimer = new Timer(1000); 70 | this.LogicTimer.Elapsed += (object sender, ElapsedEventArgs e2) => 71 | { 72 | if (this.Active) 73 | { 74 | this.UpdateSnake(); 75 | } 76 | else 77 | { 78 | this.LogicTimer.Stop(); 79 | } 80 | }; 81 | this.LogicTimer.Start(); 82 | } 83 | else if(this.GameState == 2) // Update game 84 | { 85 | var updatePacket = new CMSG_Update(); 86 | updatePacket.Deserialize(e.RawData); 87 | 88 | //Console.WriteLine("ActionType : " + updatePacket.ActionType); 89 | 90 | if(updatePacket.ActionType == 253) // Mouse down 91 | { 92 | 93 | } 94 | else if(updatePacket.ActionType == 254) // Mouse up 95 | { 96 | 97 | } 98 | else if (updatePacket.ActionType == 251) // Ping 99 | { 100 | this.SendPacket(new SMSG_p_Pong()); 101 | } 102 | else // Mouse rotation 103 | { 104 | var degrees = (short)Math.Floor(updatePacket.ActionType * 1.44); 105 | this.MySnake.CurrentAngle = degrees; 106 | //Console.WriteLine("Mouse angle : " + degrees); 107 | this.SendPacket(new SMSG_e_UpdateSnakeDirection(this.MySnake, degrees)); 108 | } 109 | } 110 | 111 | } 112 | 113 | public void UpdateSnake() 114 | { 115 | var incX = ((float)Math.Cos((Math.PI / 180) * this.MySnake.CurrentAngle) * 170); 116 | var incY = ((float)Math.Sin((Math.PI / 180) * this.MySnake.CurrentAngle) * 170); 117 | this.MySnake.Position.X += incX; 118 | this.MySnake.Position.Y += incY; 119 | this.SendPacket(new SMSG_e_UpdateSnakeDirection(this.MySnake, this.MySnake.CurrentAngle)); 120 | this.SendPacket(new SMSG_G_UpdateSnake(this.MySnake)); 121 | } 122 | 123 | public void SendPacket(IPacket packet) 124 | { 125 | var bs = packet.Serialize(); 126 | Console.WriteLine("Send packet ===> " + packet.GetType().Name + " (len: " + bs.Length + ")"); 127 | this.Send(bs); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /SlitherNET/Network/Packets/Client/CMSG_SetUsername.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace SlitherNET.Network.Packets.Client 9 | { 10 | public class CMSG_SetUsername : IPacket 11 | { 12 | public char ProtocolId 13 | { 14 | get 15 | { 16 | throw new NotImplementedException(); 17 | } 18 | } 19 | 20 | public string Username { get; set; } 21 | public byte SkinId { get; set; } 22 | 23 | public void Deserialize(byte[] data) 24 | { 25 | var reader = new BigEndianReader(new MemoryStream(data)); 26 | reader.ReadByte(); 27 | reader.ReadByte(); 28 | this.SkinId = reader.ReadByte(); 29 | this.Username = reader.ReadEndString(); 30 | } 31 | 32 | public byte[] Serialize() 33 | { 34 | throw new NotImplementedException(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SlitherNET/Network/Packets/Client/CMSG_Update.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace SlitherNET.Network.Packets.Client 9 | { 10 | public class CMSG_Update : IPacket 11 | { 12 | public char ProtocolId 13 | { 14 | get 15 | { 16 | throw new NotImplementedException(); 17 | } 18 | } 19 | 20 | public byte ActionType { get; set; } 21 | 22 | public void Deserialize(byte[] data) 23 | { 24 | var reader = new BigEndianReader(new MemoryStream(data)); 25 | this.ActionType = reader.ReadByte(); 26 | } 27 | 28 | public byte[] Serialize() 29 | { 30 | throw new NotImplementedException(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /SlitherNET/Network/Packets/IPacket.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SlitherNET.Network.Packets 8 | { 9 | public interface IPacket 10 | { 11 | char ProtocolId { get; } 12 | byte[] Serialize(); 13 | void Deserialize(byte[] data); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SlitherNET/Network/Packets/Server/SMSG_F_MapFoods.cs: -------------------------------------------------------------------------------- 1 | using SlitherNET.Game; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace SlitherNET.Network.Packets.Server 10 | { 11 | public class SMSG_F_MapFoods : IPacket 12 | { 13 | public char ProtocolId 14 | { 15 | get 16 | { 17 | return 'F'; 18 | } 19 | } 20 | 21 | public List Foods { get; set; } 22 | 23 | public SMSG_F_MapFoods(List foods) 24 | { 25 | this.Foods = foods; 26 | } 27 | 28 | public void Deserialize(byte[] data) 29 | { 30 | throw new NotImplementedException(); 31 | } 32 | 33 | public byte[] Serialize() 34 | { 35 | var bytes = new byte[3 + (6 * this.Foods.Count)]; 36 | var writer = new BigEndianWriter(new MemoryStream(bytes)); 37 | 38 | writer.WriteByte(0); 39 | writer.WriteByte(0); 40 | writer.WriteByte(Convert.ToByte(this.ProtocolId)); 41 | foreach(var food in this.Foods) 42 | { 43 | writer.WriteByte(food.Color); 44 | writer.WriteShort((short)food.Position.X); 45 | writer.WriteShort((short)food.Position.Y); 46 | writer.WriteByte(food.Color); 47 | } 48 | 49 | return bytes; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /SlitherNET/Network/Packets/Server/SMSG_G_UpdateSnake.cs: -------------------------------------------------------------------------------- 1 | using SlitherNET.Game; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace SlitherNET.Network.Packets.Server 10 | { 11 | public class SMSG_G_UpdateSnake : IPacket 12 | { 13 | public char ProtocolId 14 | { 15 | get 16 | { 17 | return 'g'; 18 | } 19 | } 20 | 21 | public Snake @Snake { get; set; } 22 | 23 | public SMSG_G_UpdateSnake(Snake snake) 24 | { 25 | this.Snake = snake; 26 | } 27 | 28 | public void Deserialize(byte[] data) 29 | { 30 | throw new NotImplementedException(); 31 | } 32 | 33 | public byte[] Serialize() 34 | { 35 | var bytes = new byte[30]; 36 | var writer = new BigEndianWriter(new MemoryStream(bytes)); 37 | 38 | writer.WriteByte(0); 39 | writer.WriteByte(0); 40 | writer.WriteByte(Convert.ToByte(this.ProtocolId)); 41 | writer.WriteShort((short)this.Snake.ID); 42 | writer.WriteShort((short)(this.Snake.Position.X)); 43 | writer.WriteShort((short)(this.Snake.Position.Y)); 44 | 45 | return bytes; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /SlitherNET/Network/Packets/Server/SMSG_a_InitialPacket.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace SlitherNET.Network.Packets.Server 9 | { 10 | public class SMSG_a_InitialPacket : IPacket 11 | { 12 | public char ProtocolId 13 | { 14 | get 15 | { 16 | return 'a'; 17 | } 18 | } 19 | 20 | public int Radius { get; set; } 21 | 22 | public SMSG_a_InitialPacket(int radius) 23 | { 24 | this.Radius = radius; 25 | } 26 | 27 | public void Deserialize(byte[] data) 28 | { 29 | throw new NotImplementedException(); 30 | } 31 | 32 | public byte[] Serialize() 33 | { 34 | var bytes = new byte[30]; 35 | var writer = new BigEndianWriter(new MemoryStream(bytes)); 36 | 37 | writer.WriteByte(0); 38 | writer.WriteByte(0); 39 | writer.WriteByte(Convert.ToByte(this.ProtocolId)); 40 | writer.WriteInt24(this.Radius); 41 | writer.WriteShort(411); 42 | writer.WriteShort(480); 43 | writer.WriteShort(130); 44 | writer.WriteByte((byte)4.8 * 10); 45 | writer.WriteShort((short) 4.25 * 100); 46 | writer.WriteShort((short) 0.5f * 100); 47 | writer.WriteShort((short) 12 * 100); 48 | writer.WriteShort((short)(0.033 * 1E3)); 49 | writer.WriteShort((short)(0.028 * 1E3)); 50 | writer.WriteShort((short)(0.43 * 1E3)); 51 | writer.WriteByte(Metadata.PROTOCOL_VERSION); 52 | 53 | return bytes; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /SlitherNET/Network/Packets/Server/SMSG_e_UpdateSnakeDirection.cs: -------------------------------------------------------------------------------- 1 | using SlitherNET.Game; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace SlitherNET.Network.Packets.Server 10 | { 11 | public class SMSG_e_UpdateSnakeDirection : IPacket 12 | { 13 | public char ProtocolId 14 | { 15 | get 16 | { 17 | return 'e'; 18 | } 19 | } 20 | 21 | public Snake @Snake { get; set; } 22 | public double Direction { get; set; } 23 | 24 | public SMSG_e_UpdateSnakeDirection(Snake snake, double direction) 25 | { 26 | this.Snake = snake; 27 | this.Direction = direction; 28 | } 29 | 30 | public void Deserialize(byte[] data) 31 | { 32 | throw new NotImplementedException(); 33 | } 34 | 35 | public byte[] Serialize() 36 | { 37 | var bytes = new byte[10]; 38 | var writer = new BigEndianWriter(new MemoryStream(bytes)); 39 | 40 | writer.WriteByte(0); 41 | writer.WriteByte(0); 42 | writer.WriteByte(Convert.ToByte(this.ProtocolId)); 43 | writer.WriteShort((short)this.Snake.ID); 44 | writer.WriteByte((byte) this.Direction); 45 | writer.WriteByte((byte) 71); 46 | writer.WriteByte((byte) 104); 47 | 48 | return bytes; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /SlitherNET/Network/Packets/Server/SMSG_l_Leaderboard.cs: -------------------------------------------------------------------------------- 1 | using SlitherNET.Game; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace SlitherNET.Network.Packets.Server 10 | { 11 | public class SMSG_l_Leaderboard : IPacket 12 | { 13 | public char ProtocolId 14 | { 15 | get 16 | { 17 | return 'l'; 18 | } 19 | } 20 | 21 | public short Rank { get; set; } 22 | public List Snakes { get; set; } 23 | 24 | public SMSG_l_Leaderboard(short rank, List snakes) 25 | { 26 | this.Rank = rank; 27 | this.Snakes = snakes; 28 | } 29 | 30 | public void Deserialize(byte[] data) 31 | { 32 | throw new NotImplementedException(); 33 | } 34 | 35 | public byte[] Serialize() 36 | { 37 | var lengthOfUsername = 0; 38 | this.Snakes.ForEach(x => lengthOfUsername += x.Player.Username.Length); 39 | var bytes = new byte[(8 + lengthOfUsername) + (this.Snakes.Count * 7)]; 40 | var writer = new BigEndianWriter(new MemoryStream(bytes)); 41 | 42 | writer.WriteByte(0); 43 | writer.WriteByte(0); 44 | writer.WriteByte(Convert.ToByte(this.ProtocolId)); 45 | writer.WriteByte(0); 46 | writer.WriteShort(this.Rank); 47 | writer.WriteShort((short)this.Snakes.Count); 48 | foreach(var snake in this.Snakes) 49 | { 50 | writer.WriteShort(306); 51 | writer.WriteInt24(0.7810754645511785 * 16777215); 52 | writer.WriteByte((byte)snake.Skin); 53 | writer.WriteString(snake.Player.Username); 54 | } 55 | 56 | return bytes; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /SlitherNET/Network/Packets/Server/SMSG_m_MessageOfTheDay.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace SlitherNET.Network.Packets.Server 9 | { 10 | public class SMSG_m_MessageOfTheDay : IPacket 11 | { 12 | public char ProtocolId 13 | { 14 | get 15 | { 16 | throw new NotImplementedException(); 17 | } 18 | } 19 | 20 | public string Message { get; set; } 21 | public string Author { get; set; } 22 | 23 | public SMSG_m_MessageOfTheDay(string message, string author) 24 | { 25 | this.Message = message; 26 | this.Author = author; 27 | } 28 | 29 | public void Deserialize(byte[] data) 30 | { 31 | throw new NotImplementedException(); 32 | } 33 | 34 | public byte[] Serialize() 35 | { 36 | var bytes = new byte[1000]; 37 | var writer = new BigEndianWriter(new MemoryStream(bytes)); 38 | writer.WriteByte(0); 39 | writer.WriteByte(0); 40 | writer.WriteByte(Convert.ToByte('m')); 41 | writer.WriteByte((byte)(462 >> 16)); 42 | writer.WriteByte((byte)(462 >> 8)); 43 | writer.WriteByte((byte)(462 & 0xFF)); 44 | 45 | var loc1 = (int)0.580671702663404 * 16777215; 46 | writer.WriteByte((byte)(loc1 >> 16)); 47 | writer.WriteByte((byte)(loc1 >> 8)); 48 | writer.WriteByte((byte)(loc1 & 0xFF)); 49 | 50 | writer.WriteString(this.Author); 51 | writer.WriteString(this.Message); 52 | 53 | return bytes; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /SlitherNET/Network/Packets/Server/SMSG_p_Pong.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace SlitherNET.Network.Packets.Server 9 | { 10 | public class SMSG_p_Pong : IPacket 11 | { 12 | public char ProtocolId 13 | { 14 | get 15 | { 16 | return 'p'; 17 | } 18 | } 19 | 20 | public void Deserialize(byte[] data) 21 | { 22 | throw new NotImplementedException(); 23 | } 24 | 25 | public byte[] Serialize() 26 | { 27 | var bytes = new byte[3]; 28 | var writer = new BigEndianWriter(new MemoryStream(bytes)); 29 | 30 | writer.WriteByte(0); 31 | writer.WriteByte(0); 32 | writer.WriteByte(Convert.ToByte(this.ProtocolId)); 33 | 34 | return bytes; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SlitherNET/Network/Packets/Server/SMSG_s_NewSnake.cs: -------------------------------------------------------------------------------- 1 | using SlitherNET.Game; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace SlitherNET.Network.Packets.Server 10 | { 11 | public class SMSG_s_NewSnake : IPacket 12 | { 13 | public char ProtocolId 14 | { 15 | get 16 | { 17 | return 's'; 18 | } 19 | } 20 | 21 | public Snake @Snake { get; set; } 22 | 23 | public SMSG_s_NewSnake(Snake snake) 24 | { 25 | this.Snake = snake; 26 | } 27 | 28 | public void Deserialize(byte[] data) 29 | { 30 | throw new NotImplementedException(); 31 | } 32 | 33 | public byte[] Serialize() 34 | { 35 | var bytes = new byte[(37 + this.Snake.Name.Length) + (2 * this.Snake.Parts.Count)]; 36 | var writer = new BigEndianWriter(new MemoryStream(bytes)); 37 | 38 | writer.WriteByte(0); 39 | writer.WriteByte(0); 40 | writer.WriteByte(Convert.ToByte(this.ProtocolId)); 41 | writer.WriteShort((short)this.Snake.ID); 42 | writer.WriteInt24(3.1415926535 / Math.PI * 16777215); 43 | writer.WriteByte(0); 44 | writer.WriteInt24(3.1415926535 / Math.PI * 16777215); 45 | writer.WriteShort((short)this.Snake.Speed); 46 | writer.WriteInt24(0.028860630325116536 * 16777215); 47 | writer.WriteByte((byte)this.Snake.Skin); 48 | writer.WriteInt24(this.Snake.Position.X); 49 | writer.WriteInt24(this.Snake.Position.Y); 50 | writer.WriteString(this.Snake.Name); 51 | writer.WriteInt24(this.Snake.HeadPosition.X); 52 | writer.WriteInt24(this.Snake.HeadPosition.Y); 53 | foreach(var part in this.Snake.Parts) 54 | { 55 | writer.WriteByte((byte)part.Position.X); 56 | writer.WriteByte((byte)part.Position.Y); 57 | } 58 | 59 | return bytes; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /SlitherNET/Program.cs: -------------------------------------------------------------------------------- 1 | using SlitherNET.Network; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using WebSocketSharp.Server; 9 | using YamlDotNet.Serialization; 10 | using YamlDotNet.Serialization.NamingConventions; 11 | 12 | namespace SlitherNET 13 | { 14 | public class Program 15 | { 16 | public static Settings @Settings { get; set; } 17 | 18 | public static void Main(string[] args) 19 | { 20 | Console.Title = "SlitherNET"; 21 | Console.ForegroundColor = ConsoleColor.Yellow; 22 | Console.WriteLine("SlitherNET by Nightwolf"); 23 | Console.ForegroundColor = ConsoleColor.Gray; 24 | LoadSettings(); 25 | 26 | var wssv = new WebSocketServer("ws://" + Settings.Network.Addr + ":" + Settings.Network.Port); 27 | wssv.AddWebSocketService("/slither"); 28 | wssv.Start(); 29 | Console.WriteLine("Listen on " + Settings.Network.Addr + ":" + Settings.Network.Port); 30 | 31 | while (true) 32 | Console.ReadLine(); 33 | } 34 | 35 | public static void LoadSettings() 36 | { 37 | var reader = new StreamReader("Settings.yaml"); 38 | var deserializer = new Deserializer(namingConvention: new CamelCaseNamingConvention()); 39 | @Settings = deserializer.Deserialize(reader); 40 | reader.Close(); 41 | } 42 | } 43 | 44 | public class Settings 45 | { 46 | public NetworkSettings Network { get; set; } 47 | public BasicSettings Basic { get; set; } 48 | 49 | public class NetworkSettings 50 | { 51 | public string Addr { get; set; } 52 | public int Port { get; set; } 53 | } 54 | 55 | public class BasicSettings 56 | { 57 | public string Motd { get; set; } 58 | public string Caption { get; set; } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /SlitherNET/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Les informations générales relatives à un assembly dépendent de 6 | // l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations 7 | // associées à un assembly. 8 | [assembly: AssemblyTitle("SlitherNET")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SlitherNET")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly 18 | // aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de 19 | // COM, affectez la valeur true à l'attribut ComVisible sur ce type. 20 | [assembly: ComVisible(false)] 21 | 22 | // Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM 23 | [assembly: Guid("9e10e058-4316-4791-8f5c-5c66e768d9d8")] 24 | 25 | // Les informations de version pour un assembly se composent des quatre valeurs suivantes : 26 | // 27 | // Version principale 28 | // Version secondaire 29 | // Numéro de build 30 | // Révision 31 | // 32 | // Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut 33 | // en utilisant '*', comme indiqué ci-dessous : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SlitherNET/Research.txt: -------------------------------------------------------------------------------- 1 |  // Global score packet 2 | { 3 | //var bytes = new byte[1000]; 4 | //var writer = new BigEndianWriter(new MemoryStream(bytes)); 5 | //writer.WriteByte(0); 6 | //writer.WriteByte(0); 7 | //writer.WriteByte(Convert.ToByte('m')); 8 | //writer.WriteByte((byte)(462 >> 16)); 9 | //writer.WriteByte((byte)(462 >> 8)); 10 | //writer.WriteByte((byte)(462 & 0xFF)); 11 | 12 | //var loc1 = (int)0.580671702663404 * 16777215; 13 | //writer.WriteByte((byte)(loc1 >> 16)); 14 | //writer.WriteByte((byte)(loc1 >> 8)); 15 | //writer.WriteByte((byte)(loc1 & 0xFF)); 16 | 17 | //writer.WriteByte((byte) (("https://github.com/").Length + 2)); 18 | //writer.WriteUTF("https://github.com/"); 19 | //writer.WriteUTF("SlitherNET, a .net server engine for slither.io"); 20 | //this.SendPacket(bytes); 21 | 22 | //var bytes = new byte[30]; 23 | //var writer = new BigEndianWriter(new MemoryStream(bytes)); 24 | //writer.WriteByte(0); 25 | //writer.WriteByte(0); 26 | //writer.WriteByte(Convert.ToByte('v')); 27 | 28 | //System.Threading.Thread.Sleep(3000); 29 | //this.Send(bytes); 30 | } 31 | -------------------------------------------------------------------------------- /SlitherNET/Settings.yaml: -------------------------------------------------------------------------------- 1 | # Configuration file for SlitherNET 2 | # By Nightwolf 3 | # https://github.com/nightwolf93/SlitherNET 4 | # File version : 1.0 5 | 6 | network: 7 | addr: 127.0.0.1 8 | port: 444 9 | 10 | basic: 11 | motd: 'SlitherNET, a .net server engine for slither.io' 12 | caption: 'https://github.com/nightwolf93/SlitherNET' 13 | -------------------------------------------------------------------------------- /SlitherNET/SlitherNET.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {9E10E058-4316-4791-8F5C-5C66E768D9D8} 8 | Exe 9 | Properties 10 | SlitherNET 11 | SlitherNET 12 | v4.5.2 13 | 512 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | true 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | ..\packages\WebSocketSharp.1.0.3-rc9\lib\websocket-sharp.dll 48 | True 49 | 50 | 51 | ..\packages\YamlDotNet.3.8.0\lib\net35\YamlDotNet.dll 52 | True 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | Always 84 | 85 | 86 | 87 | 88 | 89 | 90 | 97 | -------------------------------------------------------------------------------- /SlitherNET/bin/Debug/Settings.yaml: -------------------------------------------------------------------------------- 1 | # Configuration file for SlitherNET 2 | # By Nightwolf 3 | # https://github.com/nightwolf93/SlitherNET 4 | # File version : 1.0 5 | 6 | network: 7 | addr: 127.0.0.1 8 | port: 444 9 | 10 | basic: 11 | motd: 'SlitherNET, a .net server engine for slither.io' 12 | caption: 'https://github.com/nightwolf93/SlitherNET' 13 | -------------------------------------------------------------------------------- /SlitherNET/bin/Debug/SlitherNET.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nightwolf93/SlitherNET/42e48b08a5e870da62992431c01d063442f7a667/SlitherNET/bin/Debug/SlitherNET.exe -------------------------------------------------------------------------------- /SlitherNET/bin/Debug/SlitherNET.exe.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SlitherNET/bin/Debug/SlitherNET.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nightwolf93/SlitherNET/42e48b08a5e870da62992431c01d063442f7a667/SlitherNET/bin/Debug/SlitherNET.pdb -------------------------------------------------------------------------------- /SlitherNET/bin/Debug/SlitherNET.vshost.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nightwolf93/SlitherNET/42e48b08a5e870da62992431c01d063442f7a667/SlitherNET/bin/Debug/SlitherNET.vshost.exe -------------------------------------------------------------------------------- /SlitherNET/bin/Debug/SlitherNET.vshost.exe.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SlitherNET/bin/Debug/SlitherNET.vshost.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /SlitherNET/bin/Debug/YamlDotNet.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nightwolf93/SlitherNET/42e48b08a5e870da62992431c01d063442f7a667/SlitherNET/bin/Debug/YamlDotNet.dll -------------------------------------------------------------------------------- /SlitherNET/bin/Debug/YamlDotNet.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nightwolf93/SlitherNET/42e48b08a5e870da62992431c01d063442f7a667/SlitherNET/bin/Debug/YamlDotNet.pdb -------------------------------------------------------------------------------- /SlitherNET/bin/Debug/websocket-sharp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nightwolf93/SlitherNET/42e48b08a5e870da62992431c01d063442f7a667/SlitherNET/bin/Debug/websocket-sharp.dll -------------------------------------------------------------------------------- /SlitherNET/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/WebSocketSharp.1.0.3-rc9/WebSocketSharp.1.0.3-rc9.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nightwolf93/SlitherNET/42e48b08a5e870da62992431c01d063442f7a667/packages/WebSocketSharp.1.0.3-rc9/WebSocketSharp.1.0.3-rc9.nupkg -------------------------------------------------------------------------------- /packages/WebSocketSharp.1.0.3-rc9/lib/websocket-sharp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nightwolf93/SlitherNET/42e48b08a5e870da62992431c01d063442f7a667/packages/WebSocketSharp.1.0.3-rc9/lib/websocket-sharp.dll --------------------------------------------------------------------------------