├── .gitattributes ├── .gitignore ├── .idea ├── .gitignore └── .idea.TeeSharp │ └── .idea │ ├── .gitignore │ ├── encodings.xml │ ├── indexLayout.xml │ ├── projectSettingsUpdater.xml │ └── vcs.xml ├── Examples ├── Examples.BasicServer │ ├── Examples.BasicServer.csproj │ ├── Program.cs │ └── Properties │ │ └── PublishProfiles │ │ └── FolderProfile.pubxml ├── Examples.MapParser │ ├── Examples.MapParser.csproj │ └── Program.cs ├── Examples.MasterServer │ ├── Examples.MasterServer.csproj │ └── Program.cs └── Examples.OverrideServer │ ├── Examples.OverrideServer.csproj │ └── Program.cs ├── README.md ├── TeeSharp.Benchmark ├── TeeSharp.Benchmark.csproj └── src │ ├── EndPointCompareBenchmark.cs │ ├── EquatableSnapshotPlayerInput.cs │ ├── MarshalBenchmark.cs │ └── Program.cs ├── TeeSharp.Common ├── TeeSharp.Common.csproj └── src │ ├── Base │ ├── FS.cs │ ├── MathHelper.cs │ ├── Pair.cs │ └── Vector2.cs │ ├── Config │ ├── Config.cs │ ├── ConfigFlags.cs │ ├── ConfigInt.cs │ ├── ConfigString.cs │ └── abstract │ │ ├── BaseConfig.cs │ │ └── ConfigVariable.cs │ ├── Console │ ├── ConsoleCommand.cs │ ├── ConsoleCommandResult.cs │ ├── GameConsole.cs │ └── abstract │ │ └── BaseGameConsole.cs │ ├── Enums │ ├── ChatMode.cs │ ├── ClientState.cs │ ├── CollisionFlags.cs │ ├── CoreEvents.cs │ ├── Emote.cs │ ├── Emoticon.cs │ ├── FlagStates.cs │ ├── GameFlags.cs │ ├── GameMessage.cs │ ├── GameStateFlags.cs │ ├── GameplayMessage.cs │ ├── HookState.cs │ ├── MapEntities.cs │ ├── MapTiles.cs │ ├── MsgFlags.cs │ ├── NetworkMessages.cs │ ├── Pickup.cs │ ├── PlayerFlags.cs │ ├── SkinPart.cs │ ├── SnapshotItems.cs │ ├── Sound.cs │ ├── SpectatorMode.cs │ ├── Team.cs │ ├── Vote.cs │ └── Weapon.cs │ ├── Game │ ├── CharacterCore.cs │ ├── DefaultKernelConfig.cs │ ├── SkinPartParams.cs │ ├── WorldCore.cs │ ├── abstract │ │ └── BaseCharacterCore.cs │ └── map │ │ ├── MapCollision.cs │ │ ├── MapLayers.cs │ │ └── abstract │ │ ├── BaseMapCollision.cs │ │ └── BaseMapLayers.cs │ ├── Protocol │ ├── GameMsgUnpacker.cs │ ├── IClampedMaxClients.cs │ ├── MsgPacker.cs │ ├── abstract │ │ ├── BaseGameMessage.cs │ │ └── BaseGameMsgUnpacker.cs │ ├── messages │ │ ├── GameMsg_ClCallVote.cs │ │ ├── GameMsg_ClEmoticon.cs │ │ ├── GameMsg_ClKill.cs │ │ ├── GameMsg_ClReadyChange.cs │ │ ├── GameMsg_ClSay.cs │ │ ├── GameMsg_ClSetSpectatorMode.cs │ │ ├── GameMsg_ClSetTeam.cs │ │ ├── GameMsg_ClStartInfo.cs │ │ ├── GameMsg_ClVote.cs │ │ ├── GameMsg_DeClientEnter.cs │ │ ├── GameMsg_DeClientLeave.cs │ │ ├── GameMsg_SvBroadcast.cs │ │ ├── GameMsg_SvChat.cs │ │ ├── GameMsg_SvClientDrop.cs │ │ ├── GameMsg_SvClientInfo.cs │ │ ├── GameMsg_SvEmoticon.cs │ │ ├── GameMsg_SvExtraProjectile.cs │ │ ├── GameMsg_SvGameInfo.cs │ │ ├── GameMsg_SvGameMsg.cs │ │ ├── GameMsg_SvKillMsg.cs │ │ ├── GameMsg_SvMotd.cs │ │ ├── GameMsg_SvReadyToEnter.cs │ │ ├── GameMsg_SvSettings.cs │ │ ├── GameMsg_SvTeam.cs │ │ ├── GameMsg_SvTuneParams.cs │ │ ├── GameMsg_SvVoteClearOptions.cs │ │ ├── GameMsg_SvVoteOptionAdd.cs │ │ ├── GameMsg_SvVoteOptionListAdd.cs │ │ ├── GameMsg_SvVoteOptionRemove.cs │ │ ├── GameMsg_SvVoteSet.cs │ │ ├── GameMsg_SvVoteStatus.cs │ │ └── GameMsg_SvWeaponPickup.cs │ └── snapshot_items │ │ ├── SnapshotCharacter.cs │ │ ├── SnapshotCharacterCore.cs │ │ ├── SnapshotDemoClientInfo.cs │ │ ├── SnapshotDemoGameInfo.cs │ │ ├── SnapshotDemoTuneParams.cs │ │ ├── SnapshotEventDamage.cs │ │ ├── SnapshotEventDeath.cs │ │ ├── SnapshotEventExplosion.cs │ │ ├── SnapshotEventHammerHit.cs │ │ ├── SnapshotEventSoundWorld.cs │ │ ├── SnapshotEventSpawn.cs │ │ ├── SnapshotFlag.cs │ │ ├── SnapshotGameData.cs │ │ ├── SnapshotGameDataFlag.cs │ │ ├── SnapshotGameDataTeam.cs │ │ ├── SnapshotLaser.cs │ │ ├── SnapshotPickup.cs │ │ ├── SnapshotPlayerInfo.cs │ │ ├── SnapshotPlayerInput.cs │ │ ├── SnapshotProjectile.cs │ │ └── SnapshotSpectatorInfo.cs │ ├── Snapshots │ ├── Snapshot.cs │ ├── SnapshotBuilder.cs │ ├── SnapshotDelta.cs │ ├── SnapshotIdPool.cs │ ├── SnapshotInfo.cs │ ├── SnapshotItem.cs │ ├── SnapshotItemsInfo.cs │ ├── SnapshotStorage.cs │ └── abstract │ │ ├── BaseSnapshotEvent.cs │ │ └── BaseSnapshotItem.cs │ ├── Storage │ ├── Storage.cs │ └── abstract │ │ └── BaseStorage.cs │ └── Tuning │ ├── TuningParameter.cs │ ├── TuningParams.cs │ └── abstract │ └── BaseTuningParams.cs ├── TeeSharp.Core ├── TeeSharp.Core.csproj └── src │ ├── BidirectionalList.cs │ ├── Crc32.cs │ ├── Debug │ ├── Debug.cs │ ├── ILogger.cs │ ├── ILoggerHandler.cs │ ├── Logger.cs │ └── LoggerHandler.cs │ ├── Extensions │ ├── ArrayExtensions.cs │ ├── MarshalExtensions.cs │ └── StringExtensions.cs │ ├── IoC │ ├── Container.cs │ ├── ContainerExtensions.cs │ └── IServiceBinder.cs │ ├── Kernel │ ├── BaseInterface.cs │ ├── Binder.cs │ ├── IKernel.cs │ ├── IKernelConfig.cs │ └── Kernel.cs │ ├── RNG.cs │ ├── SanitizeType.cs │ ├── Secure.cs │ └── Time.cs ├── TeeSharp.Demo ├── TeeSharp.Demo.csproj └── src │ └── Class1.cs ├── TeeSharp.Map ├── TeeSharp.Map.csproj └── src │ ├── Datafile │ ├── DataFile.cs │ ├── DataFileReader.cs │ ├── DataFileWriter.cs │ └── DataFiles │ │ ├── DataFileHeader.cs │ │ ├── DataFileItem.cs │ │ ├── DataFileItemType.cs │ │ └── DataFileVersionHeader.cs │ ├── LayerType.cs │ ├── MapContainer.cs │ ├── MapItemTypes.cs │ └── MapItems │ ├── Color.cs │ ├── MapItemGroup.cs │ ├── MapItemImage.cs │ ├── MapItemInfo.cs │ ├── MapItemLayer.cs │ ├── MapItemLayerQuads.cs │ ├── MapItemLayerTilemap.cs │ ├── MapItemVersion.cs │ ├── Point.cs │ ├── Quad.cs │ └── Tile.cs ├── TeeSharp.MasterServer ├── TeeSharp.MasterServer.csproj └── src │ ├── CountryInfo.cs │ ├── MasterServerAddr.cs │ ├── MasterServerBrowser.cs │ ├── MasterServerHelper.cs │ ├── MasterServerPackets.cs │ ├── ServerInfo.cs │ └── ServersSnapshot.cs ├── TeeSharp.Network ├── TeeSharp.Network.csproj └── src │ ├── Abstract │ ├── BaseChunkReceiver.cs │ ├── BaseNetworkBan.cs │ ├── BaseNetworkClient.cs │ ├── BaseNetworkConnection.cs │ ├── BaseNetworkServer.cs │ ├── BaseTokenCache.cs │ └── BaseTokenManager.cs │ ├── Chunk.cs │ ├── ChunkConstruct.cs │ ├── ChunkHeader.cs │ ├── ChunkReceiver.cs │ ├── ChunkResend.cs │ ├── Enums │ ├── ChunkFlags.cs │ ├── ClientState.cs │ ├── ConnectionMessages.cs │ ├── ConnectionState.cs │ ├── PacketFlags.cs │ ├── SendFlags.cs │ └── TokenFlags.cs │ ├── Extensions │ └── NetworkExtensions.cs │ ├── Huffman.cs │ ├── IntCompression.cs │ ├── NetworkBan.cs │ ├── NetworkClient.cs │ ├── NetworkConnection.cs │ ├── NetworkHelper.cs │ ├── NetworkServer.cs │ ├── Packer.cs │ ├── SendCallbackData.cs │ ├── TokenCache.cs │ ├── TokenHelper.cs │ ├── TokenManager.cs │ └── Unpacker.cs ├── TeeSharp.Server ├── TeeSharp.Server.csproj └── src │ ├── Game │ ├── Abstract │ │ ├── BaseEvents.cs │ │ ├── BaseGameContext.cs │ │ ├── BaseGameController.cs │ │ ├── BaseGameWorld.cs │ │ ├── BasePlayer.cs │ │ └── BaseVotes.cs │ ├── Entities │ │ ├── Character.cs │ │ ├── Flag.cs │ │ ├── Laser.cs │ │ ├── Pickup.cs │ │ ├── Projectile.cs │ │ └── abstract │ │ │ └── BaseCharacter.cs │ ├── Entity.cs │ ├── Events.cs │ ├── Extensions.cs │ ├── Extensions │ │ └── EntityExtensions.cs │ ├── GameContext.cs │ ├── GameController.cs │ ├── GameState.cs │ ├── GameWorld.cs │ ├── Gamemodes │ │ ├── GameControllerCTF.cs │ │ ├── GameControllerDM.cs │ │ └── GameControllerMod.cs │ ├── Player.cs │ ├── TeeInfo.cs │ └── Votes.cs │ └── Server │ ├── Abstract │ ├── BaseRegister.cs │ ├── BaseServer.cs │ └── BaseServerClient.cs │ ├── ClientInfo.cs │ ├── ClientVersion.cs │ ├── Register.cs │ ├── Server.cs │ ├── ServerClient.cs │ ├── ServerClientState.cs │ ├── ServerConfig.cs │ ├── ServerData.cs │ ├── ServerKernelConfig.cs │ └── SnapshotRate.cs ├── TeeSharp.Tests ├── TeeSharp.Tests.csproj └── src │ ├── BidirectionalListTests.cs │ ├── CommonTests.cs │ ├── ContainerTests.cs │ ├── NetworkTests.cs │ └── SnapshotTests.cs ├── TeeSharp.sln └── res └── TeeSharp.png /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Matodor/TeeSharp/df6ac231b2bfcadbfaf953f03cef93eff709f52e/.idea/.gitignore -------------------------------------------------------------------------------- /.idea/.idea.TeeSharp/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /workspace.xml -------------------------------------------------------------------------------- /.idea/.idea.TeeSharp/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/.idea.TeeSharp/.idea/indexLayout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/.idea.TeeSharp/.idea/projectSettingsUpdater.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/.idea.TeeSharp/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Examples/Examples.BasicServer/Examples.BasicServer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | Examples.BasicServer.Program 7 | 7.2 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | PreserveNewest 18 | 19 | 20 | PreserveNewest 21 | 22 | 23 | PreserveNewest 24 | 25 | 26 | PreserveNewest 27 | 28 | 29 | PreserveNewest 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Examples/Examples.BasicServer/Program.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Core; 2 | using TeeSharp.Core.IoC; 3 | using TeeSharp.Server; 4 | using TeeSharp.Server.Game; 5 | 6 | namespace Examples.BasicServer 7 | { 8 | internal class Program 9 | { 10 | internal static void Main(string[] args) 11 | { 12 | var kernel = new Kernel(new ServerKernelConfig()); 13 | var server = kernel.Get(); 14 | server.Init(args); 15 | server.AddGametype("DM"); 16 | server.AddGametype("CTF"); 17 | server.AddGametype("MOD"); 18 | server.Run(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Examples/Examples.BasicServer/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | FileSystem 9 | Release 10 | netcoreapp2.0 11 | bin\Release\PublishOutput 12 | 13 | -------------------------------------------------------------------------------- /Examples/Examples.MapParser/Examples.MapParser.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | Examples.MapParser.Program 7 | 7.2 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | PreserveNewest 21 | 22 | 23 | PreserveNewest 24 | 25 | 26 | PreserveNewest 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Examples/Examples.MapParser/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using TeeSharp.Core; 4 | using TeeSharp.Map; 5 | using TeeSharp.Map.MapItems; 6 | 7 | namespace Examples.MapParser 8 | { 9 | internal class Program 10 | { 11 | private const string MAP_NAME = "Kobra 4"; 12 | 13 | static void Main(string[] args) 14 | { 15 | using (var stream = File.OpenRead($"maps/{MAP_NAME}.map")) 16 | { 17 | if (stream == null) 18 | { 19 | Debug.Error("map", $"could not open map='{MAP_NAME}'"); 20 | } 21 | else 22 | { 23 | var mapContainer = MapContainer.Load(stream, out var error); 24 | if (mapContainer == null) 25 | { 26 | Debug.Error("map", $"error with load map='{MAP_NAME}' ({error})"); 27 | } 28 | else 29 | { 30 | Debug.Log("map", $"successful load map='{MAP_NAME}' ({error})"); 31 | ShowMapInfo(mapContainer); 32 | ExportImages(mapContainer); 33 | Debug.Log("map", "succesful parsed"); 34 | } 35 | } 36 | } 37 | 38 | Console.ReadLine(); 39 | } 40 | 41 | private static void ExportImages(MapContainer mapContainer) 42 | { 43 | mapContainer.GetType(MapItemTypes.Image, out var imagesStart, out var imagesNum); 44 | Debug.Log("map", imagesNum > 0 ? "images:" : "images not found"); 45 | 46 | for (var i = 0; i < imagesNum; i++) 47 | { 48 | var image = mapContainer.GetItem(imagesStart + i, out _, out _); 49 | var imageName = mapContainer.GetData(image.ImageName); 50 | 51 | Debug.Log("map", " " + string.Join(';', new string[] 52 | { 53 | $"name={imageName}", 54 | $"width={image.Width}", 55 | $"height={image.Height}", 56 | $"external={image.External}" 57 | })); 58 | 59 | //var imageData = mapContainer.GetData(image.ImageData); 60 | //var format = Image.DetectFormat(imageData); 61 | 62 | //using (var image32 = Image.Load(imageData)) 63 | //{ 64 | // image32.Save($"{image.ImageName}.png"); 65 | //} 66 | 67 | mapContainer.UnloadData(image.ImageName); 68 | } 69 | } 70 | 71 | private static void ShowMapInfo(MapContainer mapContainer) 72 | { 73 | Debug.Log("map", $"map size={mapContainer.Size} bytes"); 74 | Debug.Log("map", $"map crc={mapContainer.CRC}"); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Examples/Examples.MasterServer/Examples.MasterServer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | Examples.MasterServer.Program 7 | 7.2 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Examples/Examples.OverrideServer/Examples.OverrideServer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | Examples.OverrideServer.Program 7 | 7.2 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | PreserveNewest 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Examples/Examples.OverrideServer/Program.cs: -------------------------------------------------------------------------------- 1 | namespace Examples.OverrideServer 2 | { 3 | class Program 4 | { 5 | static void Main(string[] args) 6 | { 7 | 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Logo of TeeSharp](https://github.com/Matodor/TeeSharp/raw/master/res/TeeSharp.png) 2 | 3 | # TeeSharp 4 | TeeSharp is implementation of Teeworlds in .NET Core 5 | 6 | [![Discord](https://img.shields.io/discord/403578274284044299.svg?label=discord&style=for-the-badge)](https://discord.gg/qgBV9qZ) 7 | [![Website](https://img.shields.io/website-up-down-green-red/http/shields.io.svg?label=teeworlds.su&style=for-the-badge)](http://teeworlds.su/) 8 | 9 | # Documentation 10 | * TODO 11 | 12 | # Tutorials 13 | * TODO 14 | 15 | # Questions? 16 | Come talk to us here: 17 | 18 | [![Discord Server](https://discordapp.com/api/guilds/403578274284044299/embed.png?style=banner2)](https://discord.gg/qgBV9qZ) -------------------------------------------------------------------------------- /TeeSharp.Benchmark/TeeSharp.Benchmark.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | 7.2 7 | 8 | 9 | 10 | true 11 | 12 | 13 | 14 | true 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /TeeSharp.Benchmark/src/EndPointCompareBenchmark.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using BenchmarkDotNet.Attributes; 3 | using TeeSharp.Network.Extensions; 4 | 5 | namespace TeeSharp.Benchmark 6 | { 7 | public class EndPointCompareBenchmark 8 | { 9 | [Benchmark(Description = "CompareNotEqual1")] 10 | public void CompareNotEqual1() 11 | { 12 | for (var i = 0; i < 100000; i++) 13 | { 14 | var endPoint1 = new IPEndPoint(IPAddress.Parse("192.168.137.106"), 51850); 15 | var endPoint2 = new IPEndPoint(IPAddress.Parse("188.13.68.77"), 8303); 16 | var equals = endPoint1.Compare(endPoint2, true); 17 | } 18 | } 19 | 20 | [Benchmark(Description = "CompareNotEqual2")] 21 | public void CompareNotEqual2() 22 | { 23 | for (var i = 0; i < 100000; i++) 24 | { 25 | var endPoint1 = new IPEndPoint(IPAddress.Parse("192.168.137.106"), 51850); 26 | var endPoint2 = new IPEndPoint(IPAddress.Parse("188.13.68.77"), 8303); 27 | var equals = Compare2(endPoint1, endPoint2, true); 28 | } 29 | } 30 | 31 | [Benchmark(Description = "CompareEqual1")] 32 | public void CompareEqual1() 33 | { 34 | for (var i = 0; i < 100000; i++) 35 | { 36 | var endPoint1 = new IPEndPoint(IPAddress.Parse("192.168.137.106"), 51850); 37 | var endPoint2 = new IPEndPoint(IPAddress.Parse("192.168.137.106"), 51850); 38 | var equals = endPoint1.Compare(endPoint2, true); 39 | } 40 | } 41 | 42 | [Benchmark(Description = "CompareEqual2")] 43 | public void CompareEqual2() 44 | { 45 | for (var i = 0; i < 100000; i++) 46 | { 47 | var endPoint1 = new IPEndPoint(IPAddress.Parse("192.168.137.106"), 51850); 48 | var endPoint2 = new IPEndPoint(IPAddress.Parse("192.168.137.106"), 51850); 49 | var equals = Compare2(endPoint1, endPoint2, true); 50 | } 51 | } 52 | 53 | private static bool Compare2(IPEndPoint endPoint1, IPEndPoint endPoint2, bool comparePorts) 54 | { 55 | if (comparePorts && endPoint1.Port != endPoint2.Port) 56 | return false; 57 | 58 | if (endPoint1.Address.AddressFamily != endPoint2.AddressFamily) 59 | return false; 60 | 61 | var b1 = endPoint1.Address.GetAddressBytes(); 62 | var b2 = endPoint2.Address.GetAddressBytes(); 63 | 64 | if (b1.Length != b2.Length) 65 | return false; 66 | 67 | for (var i = 0; i < b1.Length; i++) 68 | { 69 | if (b1[i] != b2[i]) 70 | return false; 71 | } 72 | 73 | return true; 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /TeeSharp.Benchmark/src/EquatableSnapshotPlayerInput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BenchmarkDotNet.Attributes; 3 | using TeeSharp.Common.Enums; 4 | using TeeSharp.Common.Protocol; 5 | 6 | namespace TeeSharp.Benchmark 7 | { 8 | public class EquatableSnapshotPlayerInput 9 | { 10 | private SnapshotPlayerInput _first; 11 | private SnapshotPlayerInput _second; 12 | 13 | public EquatableSnapshotPlayerInput() 14 | { 15 | _first = new SnapshotPlayerInput() 16 | { 17 | Direction = -1, 18 | PlayerFlags = PlayerFlags.Admin | PlayerFlags.Bot | PlayerFlags.Dead, 19 | WantedWeapon = Weapon.Grenade, 20 | Hook = 1, 21 | Jump = 1, 22 | TargetY = 123, 23 | PreviousWeapon = Weapon.Ninja, 24 | Fire = 555, 25 | NextWeapon = Weapon.Hammer, 26 | TargetX = 999, 27 | }; 28 | 29 | _second = new SnapshotPlayerInput() 30 | { 31 | Direction = -1, 32 | PlayerFlags = PlayerFlags.Admin | PlayerFlags.Bot | PlayerFlags.Dead, 33 | WantedWeapon = Weapon.Grenade, 34 | Hook = 1, 35 | Jump = 1, 36 | TargetY = 123, 37 | PreviousWeapon = Weapon.Ninja, 38 | Fire = 555, 39 | NextWeapon = Weapon.Hammer, 40 | TargetX = 999, 41 | }; 42 | } 43 | 44 | [Benchmark] 45 | public void MethodEquals() 46 | { 47 | for (var i = 0; i < 100000; i++) 48 | { 49 | var equals = _first.Equals(_second); 50 | } 51 | } 52 | 53 | [Benchmark] 54 | public void MethodSequenceEqual() 55 | { 56 | for (var i = 0; i < 100000; i++) 57 | { 58 | var data1 = _first.ToArray().AsSpan(); 59 | var data2 = _second.ToArray().AsSpan(); 60 | var equals = data1.SequenceEqual(data2); 61 | } 62 | } 63 | 64 | [Benchmark] 65 | public void MethodMarshal() 66 | { 67 | for (var i = 0; i < 100000; i++) 68 | { 69 | var data1 = _first.ToArray(); 70 | var data2 = _second.ToArray(); 71 | var equals = true; 72 | 73 | for (var index = 0; index < data1.Length; index++) 74 | { 75 | if (data1[index] != data2[index]) 76 | { 77 | equals = false; 78 | break; 79 | } 80 | } 81 | } 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /TeeSharp.Benchmark/src/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BenchmarkDotNet.Running; 3 | 4 | namespace TeeSharp.Benchmark 5 | { 6 | internal class Program 7 | { 8 | static void Main(string[] args) 9 | { 10 | string result; 11 | int number; 12 | 13 | var benchmarks = new Type[] 14 | { 15 | typeof(MarshalBenchmark), 16 | typeof(EndPointCompareBenchmark), 17 | typeof(EquatableSnapshotPlayerInput), 18 | }; 19 | 20 | do 21 | { 22 | Console.WriteLine("Select banchmark:"); 23 | for (var i = 0; i < benchmarks.Length; i++) 24 | { 25 | Console.WriteLine($"\t{i} - {benchmarks[i].Name}"); 26 | } 27 | 28 | Console.Write("\nWrite number: "); 29 | result = Console.ReadLine(); 30 | 31 | } while (!int.TryParse(result, out number) || number < 0 || number >= benchmarks.Length); 32 | 33 | BenchmarkRunner.Run(benchmarks[number]); 34 | Console.ReadLine(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /TeeSharp.Common/TeeSharp.Common.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | 7.2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /TeeSharp.Common/src/Base/FS.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TeeSharp.Common 4 | { 5 | public static class FS 6 | { 7 | public static string WorkingDirectory() 8 | { 9 | return AppDomain.CurrentDomain.BaseDirectory; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Base/Pair.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common 2 | { 3 | public class Pair 4 | { 5 | public T First { get; set; } 6 | public U Second { get; set; } 7 | 8 | public Pair(T first, U second) 9 | { 10 | First = first; 11 | Second = second; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Base/Vector2.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common 2 | { 3 | public struct Vector2 4 | { 5 | public static Vector2 Zero = new Vector2(0, 0); 6 | public static Vector2 One = new Vector2(1, 1); 7 | 8 | public float Length => (float) System.Math.Sqrt(x * x + y * y); 9 | 10 | public Vector2 Normalized 11 | { 12 | get 13 | { 14 | var l = 1f / Length; 15 | return new Vector2(x * l, y * l); 16 | } 17 | } 18 | 19 | public float x; 20 | public float y; 21 | 22 | public Vector2(float x, float y) 23 | { 24 | this.x = x; 25 | this.y = y; 26 | } 27 | 28 | public override string ToString() 29 | { 30 | return x + " " + y; 31 | } 32 | 33 | public static Vector2 operator -(Vector2 v) 34 | { 35 | return new Vector2(-v.x, -v.y); 36 | } 37 | 38 | public static Vector2 operator -(Vector2 l, Vector2 r) 39 | { 40 | return new Vector2(l.x - r.x, l.y - r.y); 41 | } 42 | 43 | public static Vector2 operator +(Vector2 l, Vector2 r) 44 | { 45 | return new Vector2(l.x + r.x, l.y + r.y); 46 | } 47 | 48 | public static Vector2 operator *(float v, Vector2 r) 49 | { 50 | return new Vector2(r.x * v, r.y * v); 51 | } 52 | 53 | public static Vector2 operator *(Vector2 l, float v) 54 | { 55 | return new Vector2(l.x * v, l.y * v); 56 | } 57 | 58 | public static Vector2 operator *(Vector2 l, Vector2 r) 59 | { 60 | return new Vector2(l.x * r.x, l.y * r.y); 61 | } 62 | 63 | public static Vector2 operator /(float v, Vector2 r) 64 | { 65 | return new Vector2(r.x / v, r.y / v); 66 | } 67 | 68 | public static Vector2 operator /(Vector2 l, float v) 69 | { 70 | return new Vector2(l.x / v, l.y / v); 71 | } 72 | 73 | public static Vector2 operator /(Vector2 l, Vector2 r) 74 | { 75 | return new Vector2(l.x / r.x, l.y / r.y); 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Config/ConfigFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TeeSharp.Common.Config 4 | { 5 | [Flags] 6 | public enum ConfigFlags 7 | { 8 | Save = 1 << 0, 9 | Client = 1 << 1, 10 | Server = 1 << 2, 11 | Store = 1 << 3, 12 | Master = 1 << 4, 13 | Econ = 1 << 5, 14 | 15 | All = Save | Client | Server | Store | Master | Econ 16 | } 17 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Config/ConfigInt.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Config 2 | { 3 | public class ConfigInt : ConfigVariable 4 | { 5 | public int Value 6 | { 7 | get => _value; 8 | set => _value = System.Math.Clamp(value, Min, Max); 9 | } 10 | 11 | public int Min { get; set; } 12 | public int Max { get; set; } 13 | public readonly int DefaultValue; 14 | 15 | private int _value; 16 | 17 | public ConfigInt(string cmd, int def, int min, int max, 18 | ConfigFlags flags, string desc) : base(cmd, flags, desc) 19 | { 20 | Min = min; 21 | Max = max; 22 | Value = def; 23 | DefaultValue = def; 24 | } 25 | 26 | public override string AsString() 27 | { 28 | return Value.ToString(); 29 | } 30 | 31 | public override int AsInt() 32 | { 33 | return Value; 34 | } 35 | 36 | public override bool AsBoolean() 37 | { 38 | return Value != 0; 39 | } 40 | 41 | public override string ToString() 42 | { 43 | return Value.ToString(); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Config/ConfigString.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Config 2 | { 3 | public class ConfigString : ConfigVariable 4 | { 5 | public int MaxLength { get; set; } 6 | public string Value { get; set; } 7 | public readonly string DefaultValue; 8 | 9 | public ConfigString(string cmd, int maxLength, string def, 10 | ConfigFlags flags, string desc) : base(cmd, flags, desc) 11 | { 12 | MaxLength = maxLength; 13 | Value = def; 14 | DefaultValue = def; 15 | } 16 | 17 | public override string AsString() 18 | { 19 | return Value; 20 | } 21 | 22 | public override int AsInt() 23 | { 24 | throw new System.NotImplementedException(); 25 | } 26 | 27 | public override bool AsBoolean() 28 | { 29 | throw new System.NotImplementedException(); 30 | } 31 | 32 | public override string ToString() 33 | { 34 | return Value; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Config/abstract/BaseConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using TeeSharp.Core; 4 | 5 | namespace TeeSharp.Common.Config 6 | { 7 | public abstract class BaseConfig : BaseInterface, IEnumerable> 8 | { 9 | public virtual ConfigVariable this[string key] => Variables[key]; 10 | 11 | protected virtual IDictionary Variables { get; set; } 12 | protected virtual ConfigFlags SaveMask { get; set; } 13 | 14 | protected abstract void AppendVariables(IDictionary variables); 15 | protected abstract void Reset(); 16 | 17 | public abstract void Init(ConfigFlags saveMask); 18 | public abstract void Save(string fileName); 19 | public abstract void RestoreString(); 20 | public abstract IEnumerator> GetEnumerator(); 21 | 22 | IEnumerator IEnumerable.GetEnumerator() 23 | { 24 | return GetEnumerator(); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Config/abstract/ConfigVariable.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Config 2 | { 3 | public abstract class ConfigVariable 4 | { 5 | public readonly string ConsoleCommand; 6 | public readonly ConfigFlags Flags; 7 | public readonly string Description; 8 | 9 | public abstract string AsString(); 10 | public abstract int AsInt(); 11 | public abstract bool AsBoolean(); 12 | 13 | public static implicit operator string(ConfigVariable v) 14 | { 15 | return v.AsString(); 16 | } 17 | 18 | public static implicit operator int(ConfigVariable v) 19 | { 20 | return v.AsInt(); 21 | } 22 | 23 | public static implicit operator bool(ConfigVariable v) 24 | { 25 | return v.AsBoolean(); 26 | } 27 | 28 | protected ConfigVariable(string cmd, ConfigFlags flags, string desc) 29 | { 30 | ConsoleCommand = cmd; 31 | Flags = flags; 32 | Description = desc; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Console/ConsoleCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TeeSharp.Common.Config; 3 | 4 | namespace TeeSharp.Common.Console 5 | { 6 | public delegate void CommandCallback(ConsoleCommandResult commandResult, int clientId, ref object data); 7 | 8 | public class ConsoleCommand 9 | { 10 | public event CommandCallback Executed; 11 | 12 | public const int MaxCmdLength = 32; 13 | public const int MaxDescLength = 96; 14 | public const int MaxParamsLength = 16; 15 | 16 | public const char ParameterString = 's'; 17 | public const char ParameterFloat = 'f'; 18 | public const char ParameterInt = 'i'; 19 | public const char ParameterRest = 'r'; 20 | public const char ParameterOptional = '?'; 21 | 22 | public int AccessLevel { get; set; } 23 | public readonly string Cmd; 24 | 25 | public readonly string ParametersFormat; 26 | public readonly ConfigFlags Flags; 27 | public readonly string Description; 28 | 29 | public object Data; 30 | 31 | public ConsoleCommand( 32 | string cmd, 33 | string format, 34 | string description, 35 | ConfigFlags flags, 36 | object data) 37 | { 38 | Cmd = cmd.Trim(); 39 | ParametersFormat = format.Trim().Replace("??", "?"); 40 | Flags = flags; 41 | Description = description; 42 | Data = data; 43 | 44 | if (string.IsNullOrEmpty(Cmd)) 45 | throw new Exception("ConsoleCommand empty cmd"); 46 | } 47 | 48 | public void Invoke(ConsoleCommandResult result, int clientId) 49 | { 50 | Executed?.Invoke(result, clientId, ref Data); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/ChatMode.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum ChatMode 4 | { 5 | None = 0, 6 | All, 7 | Team, 8 | Whisper, 9 | 10 | NumModes, 11 | } 12 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/ClientState.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum ClientState 4 | { 5 | Offline = 0, 6 | Connecting, 7 | Loading, 8 | Online, 9 | Demoplayback, 10 | Quiting, 11 | } 12 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/CollisionFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TeeSharp.Common.Enums 4 | { 5 | [Flags] 6 | public enum CollisionFlags 7 | { 8 | None = 0, 9 | Solid = 1 << 0, 10 | Death = 1 << 1, 11 | NoHook = 1 << 2 12 | } 13 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/CoreEvents.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TeeSharp.Common.Enums 4 | { 5 | [Flags] 6 | public enum CoreEvents 7 | { 8 | None = 0, 9 | GroundJump = 1 << 0, 10 | AirJump = 1 << 1, 11 | HookAttachPlayer = 1 << 2, 12 | HookAttachGround = 1 << 3, 13 | HookHitNoHook = 1 << 4, 14 | } 15 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/Emote.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum Emote 4 | { 5 | Normal = 0, 6 | Pain, 7 | Happy, 8 | Surprise, 9 | Angry, 10 | Blink, 11 | 12 | NumEmotes, 13 | } 14 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/Emoticon.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum Emoticon 4 | { 5 | Oop = 0, 6 | Exclamation, 7 | Hearts, 8 | Drop, 9 | DotDotDot, 10 | Music, 11 | Sorry, 12 | Ghost, 13 | Sushi, 14 | SplatTee, 15 | DevilTee, 16 | Zomg, 17 | Zzz, 18 | Wtf, 19 | Eyes, 20 | Question, 21 | 22 | NumEmoticons, 23 | } 24 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/FlagStates.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum FlagStates 4 | { 5 | Missing = -3, 6 | AtStand, 7 | Taken, 8 | } 9 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/GameFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TeeSharp.Common.Enums 4 | { 5 | [Flags] 6 | public enum GameFlags 7 | { 8 | None = 0, 9 | Teams = 1 << 0, 10 | Flags = 1 << 1, 11 | Survival = 1 << 2, 12 | } 13 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/GameMessage.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum GameMessage 4 | { 5 | Invalid = 0, 6 | 7 | ServerMotd, 8 | ServerBroadcast, 9 | ServerChat, 10 | ServerTeam, 11 | ServerKillMessage, 12 | ServerTuneParams, 13 | ServerExtraProjectile, 14 | ServerReadyToEnter, 15 | ServerWeaponPickup, 16 | ServerEmoticon, 17 | ServerVoteClearOptions, 18 | ServerVoteOptionListAdd, 19 | ServerVoteOptionAdd, 20 | ServerVoteOptionRemove, 21 | ServerVoteSet, 22 | ServerVoteStatus, 23 | ServerSettings, 24 | ServerClientInfo, 25 | ServerGameInfo, 26 | ServerClientDrop, 27 | ServerGameMessage, 28 | 29 | DemoClientEnter, 30 | DemoClientLeave, 31 | 32 | ClientSay, 33 | ClientSetTeam, 34 | ClientSetSpectatorMode, 35 | ClientStartInfo, 36 | ClientKill, 37 | ClientReadyChange, 38 | ClientEmoticon, 39 | ClientVote, 40 | ClientCallVote, 41 | 42 | NumMessages, 43 | } 44 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/GameStateFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TeeSharp.Common.Enums 4 | { 5 | [Flags] 6 | public enum GameStateFlags 7 | { 8 | None = 0, 9 | Warmup = 1 << 0, 10 | SuddenDeath = 1 << 1, 11 | RoundOver = 1 << 2, 12 | GameOver = 1 << 3, 13 | Paused = 1 << 4, 14 | StartCountDown = 1 << 5 15 | } 16 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/GameplayMessage.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum GameplayMessage 4 | { 5 | TeamSwap = 0, 6 | SpectatorInvalidId, 7 | TeamShuffle, 8 | TeamBalance, 9 | CtfDrop, 10 | CtfReturn, 11 | TeamAll, 12 | TeamBalanceVictim, 13 | CtfGrab, 14 | CtfCapture, 15 | 16 | NumMessages 17 | } 18 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/HookState.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum HookState 4 | { 5 | Retracted = -1, 6 | Idle = 0, 7 | RetractStart = 1, 8 | RetractEnd = 3, 9 | Flying = 4, 10 | Grabbed = 5, 11 | } 12 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/MapEntities.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum MapEntities 4 | { 5 | Null = 0, 6 | Spawn, 7 | SpawnRed, 8 | SpawnBlue, 9 | FlagStandRed, 10 | FlagStandBlue, 11 | Armor, 12 | Health, 13 | WeaponShotgun, 14 | WeaponGrenade, 15 | PowerupNinja, 16 | WeaponLaser, 17 | 18 | NumEntities, 19 | EntityOffset = 255 - 16 * 4, 20 | } 21 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/MapTiles.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum MapTiles 4 | { 5 | Air = 0, 6 | Solid, 7 | Death, 8 | NoHook 9 | } 10 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/MsgFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TeeSharp.Common.Enums 4 | { 5 | [Flags] 6 | public enum MsgFlags 7 | { 8 | None = 0, 9 | Vital = 1 << 0, 10 | Flush = 1 << 1, 11 | NoRecord = 1 << 2, 12 | Record = 1 << 3, 13 | NoSend = 1 << 4, 14 | } 15 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/NetworkMessages.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum NetworkMessages 4 | { 5 | Null = 0, 6 | 7 | ClientInfo = 1, 8 | 9 | ServerMapChange, 10 | ServerMapData, 11 | ServerInfo, 12 | ServerConnectionReady, 13 | ServerSnap, 14 | ServerSnapEmpty, 15 | ServerSnapSingle, 16 | ServerSnapSmall, 17 | ServerInputTiming, 18 | ServerRconAuthOn, 19 | ServerRconAuthOff, 20 | ServerRconLine, 21 | ServerRconCommandAdd, 22 | ServerRconCommandRemove, 23 | ServerAuthChallenge, 24 | ServerAuthResult, 25 | 26 | ClientReady, 27 | ClientEnterGame, 28 | ClientInput, 29 | ClientRconCommand, 30 | ClientRconAuth, 31 | ClientRequestMapData, 32 | ClientAuthStart, 33 | ClientAuthResponse, 34 | 35 | Ping, 36 | PingReply, 37 | Error, 38 | } 39 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/Pickup.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum Pickup 4 | { 5 | Health = 0, 6 | Armor, 7 | Grenade, 8 | Shotgun, 9 | Laser, 10 | Ninja, 11 | 12 | NumPickups, 13 | } 14 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/PlayerFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TeeSharp.Common.Enums 4 | { 5 | [Flags] 6 | public enum PlayerFlags 7 | { 8 | None = 0, 9 | Admin = 1 << 0, 10 | Chatting = 1 << 1, 11 | Scoreboard = 1 << 2, 12 | Ready = 1 << 3, 13 | Dead = 1 << 4, 14 | Watching = 1 << 5, 15 | Bot = 1 << 6, 16 | 17 | All = 18 | None | 19 | Admin | 20 | Chatting | 21 | Scoreboard | 22 | Ready | 23 | Dead | 24 | Watching | 25 | Bot, 26 | } 27 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/SkinPart.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum SkinPart 4 | { 5 | Body = 0, 6 | Marking, 7 | Decoration, 8 | Hands, 9 | Feet, 10 | Eyes, 11 | 12 | NumParts 13 | } 14 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/SnapshotItems.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum SnapshotItems 4 | { 5 | Invalid = 0, 6 | 7 | PlayerInput, 8 | Projectile, 9 | Laser, 10 | Pickup, 11 | Flag, 12 | GameData, 13 | GameDataTeam, 14 | GameDataFlag, 15 | CharacterCore, // not used 16 | Character, 17 | PlayerInfo, 18 | SpectatorInfo, 19 | 20 | DemoClientInfo, 21 | DemoGameInfo, 22 | DemoTuneParams, 23 | 24 | EventCommon, 25 | EventExplosion, 26 | EventSpawn, 27 | EventHammerHit, 28 | EventDeath, 29 | EventSoundWorld, 30 | EventDamage, 31 | 32 | NumItems, 33 | } 34 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/Sound.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum Sound 4 | { 5 | GunFire = 0, 6 | ShotgunFire, 7 | GrenadeFire, 8 | HammerFire, 9 | HammerHit, 10 | NinjaFire, 11 | GrenadeExplode, 12 | NinjaHit, 13 | LaserFire, 14 | LaserBounce, 15 | WeaponSwitch, 16 | PlayerPainShort, 17 | PlayerPainLong, 18 | BodyLand, 19 | PlayerAirjump, 20 | PlayerJump, 21 | PlayerDie, 22 | PlayerSpawn, 23 | PlayerSkid, 24 | TeeCry, 25 | HookLoop, 26 | HookAttachGround, 27 | HookAttachPlayer, 28 | HookNoAttach, 29 | PickupHealth, 30 | PickupArmor, 31 | PickupGrenade, 32 | PickupShotgun, 33 | PickupNinja, 34 | WeaponSpawn, 35 | WeaponNoAmmo, 36 | Hit, 37 | ChatServer, 38 | ChatClient, 39 | ChatHighlight, 40 | CtfDrop, 41 | CtfReturn, 42 | CtfGrabPl, 43 | CtfGrabEn, 44 | CtfCapture, 45 | Menu, 46 | 47 | NumSounds, 48 | } 49 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/SpectatorMode.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum SpectatorMode 4 | { 5 | FreeView = 0, 6 | Player, 7 | FlagRed, 8 | FlagBlue, 9 | 10 | NumModes 11 | } 12 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/Team.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum Team 4 | { 5 | Spectators = -1, 6 | Red, 7 | Blue, 8 | } 9 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/Vote.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum Vote 4 | { 5 | Unknown = 0, 6 | StartOption, 7 | StartKick, 8 | StartSpectator, 9 | EndAbort, 10 | EndPass, 11 | EndFail, 12 | 13 | NumTypes, 14 | } 15 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Enums/Weapon.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Enums 2 | { 3 | public enum Weapon 4 | { 5 | Hammer = 0, 6 | Gun, 7 | Shotgun, 8 | Grenade, 9 | Laser, 10 | Ninja, 11 | 12 | NumWeapons, 13 | } 14 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Game/DefaultKernelConfig.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Console; 2 | using TeeSharp.Common.Protocol; 3 | using TeeSharp.Common.Storage; 4 | using TeeSharp.Core; 5 | using TeeSharp.Network; 6 | 7 | namespace TeeSharp.Common.Game 8 | { 9 | public class DefaultKernelConfig : IKernelConfig 10 | { 11 | public virtual void Load(IKernel kernel) 12 | { 13 | kernel.Bind().To().AsSingleton(); 14 | kernel.Bind().To().AsSingleton(); 15 | kernel.Bind().To().AsSingleton(); 16 | kernel.Bind().To().AsSingleton(); 17 | 18 | kernel.Bind().To(); 19 | kernel.Bind().To(); 20 | kernel.Bind().To(); 21 | kernel.Bind().To(); 22 | 23 | kernel.Bind().To(); 24 | kernel.Bind().To(); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Game/SkinPartParams.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Game 2 | { 3 | public class SkinPartParams 4 | { 5 | public string Name { get; set; } 6 | public bool UseCustomColor { get; set; } 7 | public int Color { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Game/WorldCore.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Game 2 | { 3 | public class WorldCore 4 | { 5 | public virtual BaseCharacterCore[] CharacterCores { get; set; } 6 | public virtual BaseTuningParams Tuning { get; set; } 7 | 8 | public WorldCore(int characters, BaseTuningParams tuning) 9 | { 10 | CharacterCores = new BaseCharacterCore[characters]; 11 | Tuning = tuning; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Game/abstract/BaseCharacterCore.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Common.Game; 3 | using TeeSharp.Common.Protocol; 4 | using TeeSharp.Core; 5 | 6 | namespace TeeSharp.Common 7 | { 8 | public abstract class BaseCharacterCore : BaseInterface 9 | { 10 | public const float TeeSize = 28.0f; 11 | 12 | public virtual bool IsPredicted { get; set; } 13 | public virtual Vector2 Position { get; set; } 14 | public virtual Vector2 Velocity { get; set; } 15 | 16 | public virtual Vector2 HookPosition { get; set; } 17 | public virtual Vector2 HookDirection { get; set; } 18 | public virtual int HookTick { get; set; } 19 | public virtual HookState HookState { get; set; } 20 | public virtual int HookedPlayer { get; set; } 21 | 22 | public virtual int Jumped { get; set; } 23 | public virtual int Direction { get; set; } 24 | public virtual int Angle { get; set; } 25 | public virtual CoreEvents TriggeredEvents { get; set; } 26 | 27 | protected virtual WorldCore World { get; set; } 28 | protected virtual BaseMapCollision MapCollision { get; set; } 29 | protected virtual SnapshotCharacter QuantizeCore { get; set; } 30 | 31 | public abstract void Init(WorldCore worldCore, BaseMapCollision mapCollision); 32 | public abstract void Reset(); 33 | public abstract void Tick(SnapshotPlayerInput input); 34 | public abstract void Move(); 35 | public abstract void Write(SnapshotCharacterCore core); 36 | public abstract void Quantize(); 37 | public abstract void Read(SnapshotCharacter core); 38 | public abstract void Fill(BaseCharacterCore from); 39 | } 40 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Game/map/MapLayers.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Map; 2 | using TeeSharp.Map.MapItems; 3 | 4 | namespace TeeSharp.Common 5 | { 6 | public class MapLayers : BaseMapLayers 7 | { 8 | public override void Init(MapContainer map) 9 | { 10 | Map = map; 11 | Map.GetType(MapItemTypes.Group, out var groupsStart, out var groupsNum); 12 | Map.GetType(MapItemTypes.Layer, out var layersStart, out var layersNum); 13 | 14 | GroupsStart = groupsStart; 15 | GroupsNum = groupsNum; 16 | LayersStart = layersStart; 17 | LayersNum = layersNum; 18 | 19 | for (var g = 0; g < GroupsNum; g++) 20 | { 21 | var group = GetGroup(g); 22 | 23 | for (var l = 0; l < group.NumLayers; l++) 24 | { 25 | var layer = GetLayer(group.StartLayer + l); 26 | 27 | if (layer.Type == LayerType.Tiles) 28 | { 29 | var tilemap = Map.GetItem( 30 | LayersStart + group.StartLayer + l, 31 | out _, 32 | out _ 33 | ); 34 | 35 | if ((tilemap.Flags & 1) == 0) // TILESLAYERFLAG_GAME 36 | continue; 37 | 38 | GameLayer = tilemap; 39 | GameGroup = group; 40 | 41 | GameGroup.OffsetX = 0; 42 | GameGroup.OffsetY = 0; 43 | GameGroup.ParallaxX = 100; 44 | GameGroup.ParallaxY = 100; 45 | 46 | if (GameGroup.Version >= 2) 47 | { 48 | GameGroup.UseClipping = 0; 49 | GameGroup.ClipX = 0; 50 | GameGroup.ClipY = 0; 51 | GameGroup.ClipW = 0; 52 | GameGroup.ClipH = 0; 53 | } 54 | 55 | break; 56 | } 57 | } 58 | } 59 | } 60 | 61 | public override MapItemGroup GetGroup(int index) 62 | { 63 | return Map.GetItem(GroupsStart + index, out _, out _); 64 | } 65 | 66 | public override MapItemLayer GetLayer(int index) 67 | { 68 | return Map.GetItem(LayersStart + index, out _, out _); 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Game/map/abstract/BaseMapCollision.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Core; 3 | using TeeSharp.Map.MapItems; 4 | 5 | namespace TeeSharp.Common 6 | { 7 | public abstract class BaseMapCollision : BaseInterface 8 | { 9 | public virtual int Width { get; protected set; } 10 | public virtual int Height { get; protected set; } 11 | 12 | protected virtual BaseMapLayers MapLayers { get; set; } 13 | protected virtual Tile[] GameLayerTiles { get; set; } 14 | 15 | public abstract void Init(BaseMapLayers mapLayers); 16 | public abstract Tile GetTile(int index); 17 | public abstract Tile GetTile(int x, int y); 18 | public abstract CollisionFlags GetTileFlags(int x, int y); 19 | public abstract CollisionFlags IntersectLine(Vector2 pos0, Vector2 pos1, out Vector2 outCollision, 20 | out Vector2 outBeforeCollision); 21 | public abstract bool TestBox(Vector2 pos, Vector2 size); 22 | public abstract void MovePoint(ref Vector2 inOutPos, ref Vector2 inOutVel, 23 | float elasticity, out int bounces); 24 | public abstract void MoveBox(ref Vector2 pos, ref Vector2 vel, Vector2 boxSize, 25 | float elasticity); 26 | 27 | protected abstract void SetTilesFlags(); 28 | 29 | public virtual CollisionFlags GetTileFlags(float x, float y) 30 | { 31 | return GetTileFlags(MathHelper.RoundToInt(x), MathHelper.RoundToInt(y)); 32 | } 33 | 34 | public virtual bool IsTileSolid(float x, float y) 35 | { 36 | return GetTileFlags( 37 | MathHelper.RoundToInt(x), 38 | MathHelper.RoundToInt(y) 39 | ).HasFlag(CollisionFlags.Solid); 40 | } 41 | 42 | public virtual bool IsTileSolid(Vector2 pos) 43 | { 44 | return IsTileSolid(pos.x, pos.y); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Game/map/abstract/BaseMapLayers.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Core; 2 | using TeeSharp.Map; 3 | using TeeSharp.Map.MapItems; 4 | 5 | namespace TeeSharp.Common 6 | { 7 | public abstract class BaseMapLayers : BaseInterface 8 | { 9 | public virtual MapItemGroup GameGroup { get; protected set; } 10 | public virtual MapItemLayerTilemap GameLayer { get; protected set; } 11 | public virtual MapContainer Map { get; protected set; } 12 | 13 | protected virtual int GroupsStart { get; set; } 14 | protected virtual int GroupsNum { get; set; } 15 | protected virtual int LayersStart { get; set; } 16 | protected virtual int LayersNum { get; set; } 17 | 18 | public abstract void Init(MapContainer map); 19 | public abstract MapItemGroup GetGroup(int index); 20 | public abstract MapItemLayer GetLayer(int index); 21 | } 22 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/IClampedMaxClients.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Protocol 2 | { 3 | public interface IClampedMaxClients 4 | { 5 | void Validate(int maxClients, ref string failedOn); 6 | } 7 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/MsgPacker.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Network; 2 | 3 | namespace TeeSharp.Common 4 | { 5 | public class MsgPacker : Packer 6 | { 7 | public MsgPacker(int msgId, bool system) 8 | { 9 | Reset(); 10 | AddInt((msgId << 1) | (system ? 1 : 0)); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/abstract/BaseGameMessage.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Core; 3 | using TeeSharp.Network; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | public abstract class BaseGameMessage 8 | { 9 | protected const SanitizeType Sanitize = 10 | SanitizeType.SanitizeCC | 11 | SanitizeType.SkipStartWhitespaces; 12 | 13 | public abstract GameMessage Type { get; } 14 | 15 | public abstract bool PackError(MsgPacker packer); 16 | public abstract bool UnPackError(UnPacker unpacker, ref string failedOn); 17 | } 18 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/abstract/BaseGameMsgUnpacker.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Core; 3 | using TeeSharp.Network; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | public abstract class BaseGameMsgUnpacker : BaseInterface 8 | { 9 | public virtual int MaxClients { get; set; } 10 | 11 | public abstract bool UnpackMessage(GameMessage msg, 12 | UnPacker unPacker, out BaseGameMessage value, out string failedOn); 13 | } 14 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_ClCallVote.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_ClCallVote : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ClientCallVote; 9 | 10 | public string VoteType { get; set; } 11 | public string Value { get; set; } 12 | public string Reason { get; set; } 13 | public bool Force { get; set; } 14 | 15 | public override bool PackError(MsgPacker packer) 16 | { 17 | packer.AddString(VoteType); 18 | packer.AddString(Value); 19 | packer.AddString(Reason); 20 | packer.AddBool(Force); 21 | return packer.Error; 22 | } 23 | 24 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 25 | { 26 | VoteType = unpacker.GetString(Sanitize); 27 | Value = unpacker.GetString(Sanitize); 28 | Reason = unpacker.GetString(Sanitize); 29 | Force = unpacker.GetBool(); 30 | 31 | return unpacker.Error; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_ClEmoticon.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_ClEmoticon : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ClientEmoticon; 9 | 10 | public Emoticon Emoticon { get; set; } 11 | 12 | public override bool PackError(MsgPacker packer) 13 | { 14 | packer.AddInt((int) Emoticon); 15 | return packer.Error; 16 | } 17 | 18 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 19 | { 20 | Emoticon = (Emoticon) unpacker.GetInt(); 21 | 22 | if (Emoticon < 0 || Emoticon >= Emoticon.NumEmoticons) 23 | failedOn = nameof(Emoticon); 24 | 25 | return unpacker.Error; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_ClKill.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_ClKill : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ClientKill; 9 | 10 | public override bool PackError(MsgPacker packer) 11 | { 12 | return packer.Error; 13 | } 14 | 15 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 16 | { 17 | return unpacker.Error; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_ClReadyChange.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_ClReadyChange : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ClientReadyChange; 9 | 10 | public override bool PackError(MsgPacker packer) 11 | { 12 | return packer.Error; 13 | } 14 | 15 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 16 | { 17 | return unpacker.Error; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_ClSay.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_ClSay : BaseGameMessage, IClampedMaxClients 7 | { 8 | public override GameMessage Type => GameMessage.ClientSay; 9 | 10 | public ChatMode ChatMode { get; set; } 11 | public int TargetId { get; set; } 12 | public string Message { get; set; } 13 | 14 | public override bool PackError(MsgPacker packer) 15 | { 16 | packer.AddInt((int) ChatMode); 17 | packer.AddInt(TargetId); 18 | packer.AddString(Message); 19 | return packer.Error; 20 | } 21 | 22 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 23 | { 24 | ChatMode = (ChatMode) unpacker.GetInt(); 25 | TargetId = unpacker.GetInt(); 26 | Message = unpacker.GetString(Sanitize); 27 | 28 | if (ChatMode < 0 || ChatMode >= ChatMode.NumModes) 29 | failedOn = nameof(ChatMode); 30 | 31 | return unpacker.Error; 32 | } 33 | 34 | public void Validate(int maxClients, ref string failedOn) 35 | { 36 | if (TargetId < -1 || TargetId >= maxClients) 37 | failedOn = nameof(TargetId); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_ClSetSpectatorMode.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_ClSetSpectatorMode : BaseGameMessage, IClampedMaxClients 7 | { 8 | public override GameMessage Type => GameMessage.ClientSetSpectatorMode; 9 | 10 | public SpectatorMode SpectatorMode { get; set; } 11 | public int SpectatorId { get; set; } 12 | 13 | public override bool PackError(MsgPacker packer) 14 | { 15 | packer.AddInt((int) SpectatorMode); 16 | packer.AddInt(SpectatorId); 17 | return packer.Error; 18 | } 19 | 20 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 21 | { 22 | SpectatorMode = (SpectatorMode) unpacker.GetInt(); 23 | SpectatorId = unpacker.GetInt(); 24 | 25 | if (SpectatorMode < 0 || SpectatorMode >= SpectatorMode.NumModes) 26 | failedOn = nameof(SpectatorMode); 27 | 28 | return unpacker.Error; 29 | } 30 | 31 | public void Validate(int maxClients, ref string failedOn) 32 | { 33 | if (SpectatorId < -1 || SpectatorId >= maxClients) 34 | failedOn = nameof(SpectatorId); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_ClSetTeam.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_ClSetTeam : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ClientSetTeam; 9 | 10 | public Team Team { get; set; } 11 | 12 | public override bool PackError(MsgPacker packer) 13 | { 14 | packer.AddInt((int) Team); 15 | return packer.Error; 16 | } 17 | 18 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 19 | { 20 | Team = (Team) unpacker.GetInt(); 21 | 22 | if (Team < Team.Spectators || Team > Team.Blue) 23 | failedOn = nameof(Team); 24 | 25 | return unpacker.Error; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_ClStartInfo.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_ClStartInfo : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ClientStartInfo; 9 | 10 | public string Name { get; set; } 11 | public string Clan { get; set; } 12 | public int Country { get; set; } 13 | 14 | public string[] SkinPartNames { get; private set; } 15 | public bool[] UseCustomColors { get; private set; } 16 | public int[] SkinPartColors { get; private set; } 17 | 18 | public GameMsg_ClStartInfo() 19 | { 20 | SkinPartNames = new string[6]; 21 | UseCustomColors = new bool[6]; 22 | SkinPartColors = new int[6]; 23 | } 24 | 25 | public override bool PackError(MsgPacker packer) 26 | { 27 | packer.AddString(Name); 28 | packer.AddString(Clan); 29 | packer.AddInt(Country); 30 | packer.AddString(SkinPartNames); 31 | packer.AddBool(UseCustomColors); 32 | packer.AddInt(SkinPartColors); 33 | return packer.Error; 34 | } 35 | 36 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 37 | { 38 | Name = unpacker.GetString(Sanitize); 39 | Clan = unpacker.GetString(Sanitize); 40 | Country = unpacker.GetInt(); 41 | unpacker.GetString(SkinPartNames, Sanitize); 42 | unpacker.GetBool(UseCustomColors); 43 | unpacker.GetInt(SkinPartColors); 44 | 45 | return unpacker.Error; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_ClVote.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_ClVote : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ClientVote; 9 | 10 | public int Vote { get; set; } 11 | 12 | public override bool PackError(MsgPacker packer) 13 | { 14 | packer.AddInt(Vote); 15 | return packer.Error; 16 | } 17 | 18 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 19 | { 20 | Vote = unpacker.GetInt(); 21 | 22 | if (Vote < -1 || Vote > 1) 23 | failedOn = nameof(Vote); 24 | 25 | return unpacker.Error; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_DeClientEnter.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_DeClientEnter : BaseGameMessage, IClampedMaxClients 7 | { 8 | public override GameMessage Type => GameMessage.DemoClientEnter; 9 | 10 | public string Name { get; set; } 11 | public int ClientId { get; set; } 12 | public Team Team { get; set; } 13 | 14 | public override bool PackError(MsgPacker packer) 15 | { 16 | packer.AddString(Name); 17 | packer.AddInt(ClientId); 18 | packer.AddInt((int) Team); 19 | return packer.Error; 20 | } 21 | 22 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 23 | { 24 | Name = unpacker.GetString(Sanitize); 25 | ClientId = unpacker.GetInt(); 26 | Team = (Team) unpacker.GetInt(); 27 | 28 | if (Team < Team.Spectators || Team > Team.Blue) 29 | failedOn = nameof(Team); 30 | 31 | return unpacker.Error; 32 | } 33 | 34 | public void Validate(int maxClients, ref string failedOn) 35 | { 36 | if (ClientId < -1 || ClientId >= maxClients) 37 | failedOn = nameof(ClientId); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_DeClientLeave.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_DeClientLeave : BaseGameMessage, IClampedMaxClients 7 | { 8 | public override GameMessage Type => GameMessage.DemoClientLeave; 9 | 10 | public string Name { get; set; } 11 | public int ClientId { get; set; } 12 | public string Reason { get; set; } 13 | 14 | public override bool PackError(MsgPacker packer) 15 | { 16 | packer.AddString(Name); 17 | packer.AddInt(ClientId); 18 | packer.AddString(Reason); 19 | return packer.Error; 20 | } 21 | 22 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 23 | { 24 | Name = unpacker.GetString(Sanitize); 25 | ClientId = unpacker.GetInt(); 26 | Reason = unpacker.GetString(Sanitize); 27 | 28 | return unpacker.Error; 29 | } 30 | 31 | public void Validate(int maxClients, ref string failedOn) 32 | { 33 | if (ClientId < -1 || ClientId >= maxClients) 34 | failedOn = nameof(ClientId); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvBroadcast.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvBroadcast : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ServerBroadcast; 9 | 10 | public string Message { get; set; } 11 | 12 | public override bool PackError(MsgPacker packer) 13 | { 14 | packer.AddString(Message); 15 | return packer.Error; 16 | } 17 | 18 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 19 | { 20 | Message = unpacker.GetString(Sanitize); 21 | return unpacker.Error; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvChat.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvChat : BaseGameMessage, IClampedMaxClients 7 | { 8 | public override GameMessage Type => GameMessage.ServerChat; 9 | 10 | public ChatMode ChatMode { get; set; } 11 | public int ClientId { get; set; } 12 | public int TargetId { get; set; } 13 | public string Message { get; set; } 14 | 15 | public override bool PackError(MsgPacker packer) 16 | { 17 | packer.AddInt((int) ChatMode); 18 | packer.AddInt(ClientId); 19 | packer.AddInt(TargetId); 20 | packer.AddString(Message); 21 | return packer.Error; 22 | } 23 | 24 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 25 | { 26 | ChatMode = (ChatMode) unpacker.GetInt(); 27 | ClientId = unpacker.GetInt(); 28 | TargetId = unpacker.GetInt(); 29 | Message = unpacker.GetString(Sanitize); 30 | 31 | if (ChatMode < 0 || ChatMode >= ChatMode.NumModes) 32 | failedOn = nameof(ChatMode); 33 | 34 | return unpacker.Error; 35 | } 36 | 37 | public void Validate(int maxClients, ref string failedOn) 38 | { 39 | if (ClientId < -1 || ClientId >= maxClients) 40 | failedOn = nameof(ClientId); 41 | if (TargetId < -1 || TargetId >= maxClients) 42 | failedOn = nameof(TargetId); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvClientDrop.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvClientDrop : BaseGameMessage, IClampedMaxClients 7 | { 8 | public override GameMessage Type => GameMessage.ServerClientDrop; 9 | 10 | public int ClientID { get; set; } 11 | public string Reason { get; set; } 12 | public bool Silent { get; set; } 13 | 14 | public override bool PackError(MsgPacker packer) 15 | { 16 | packer.AddInt(ClientID); 17 | packer.AddString(Reason); 18 | packer.AddBool(Silent); 19 | return packer.Error; 20 | } 21 | 22 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 23 | { 24 | ClientID = unpacker.GetInt(); 25 | Reason = unpacker.GetString(Sanitize); 26 | Silent = unpacker.GetBool(); 27 | 28 | return unpacker.Error; 29 | } 30 | 31 | public void Validate(int maxClients, ref string failedOn) 32 | { 33 | if (ClientID < 0 || ClientID >= maxClients) 34 | failedOn = nameof(ClientID); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvClientInfo.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvClientInfo : BaseGameMessage, IClampedMaxClients 7 | { 8 | public override GameMessage Type => GameMessage.ServerClientInfo; 9 | 10 | public int ClientID { get; set; } 11 | public bool Local { get; set; } 12 | public Team Team { get; set; } 13 | public string Name { get; set; } 14 | public string Clan { get; set; } 15 | public int Country { get; set; } 16 | 17 | public string[] SkinPartNames { get; private set; } 18 | public bool[] UseCustomColors { get; private set; } 19 | public int[] SkinPartColors { get; private set; } 20 | 21 | public bool Silent { get; set; } 22 | 23 | public GameMsg_SvClientInfo() 24 | { 25 | SkinPartNames = new string[6]; 26 | UseCustomColors = new bool[6]; 27 | SkinPartColors = new int[6]; 28 | } 29 | 30 | public override bool PackError(MsgPacker packer) 31 | { 32 | packer.AddInt(ClientID); 33 | packer.AddBool(Local); 34 | packer.AddInt((int) Team); 35 | packer.AddString(Name); 36 | packer.AddString(Clan); 37 | packer.AddInt(Country); 38 | packer.AddString(SkinPartNames); 39 | packer.AddBool(UseCustomColors); 40 | packer.AddInt(SkinPartColors); 41 | packer.AddBool(Silent); 42 | 43 | return packer.Error; 44 | } 45 | 46 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 47 | { 48 | ClientID = unpacker.GetInt(); 49 | Local = unpacker.GetBool(); 50 | Team = (Team) unpacker.GetInt(); 51 | Name = unpacker.GetString(Sanitize); 52 | Clan = unpacker.GetString(Sanitize); 53 | Country = unpacker.GetInt(); 54 | 55 | unpacker.GetString(SkinPartNames, Sanitize); 56 | unpacker.GetBool(UseCustomColors); 57 | unpacker.GetInt(SkinPartColors); 58 | 59 | Silent = unpacker.GetBool(); 60 | 61 | 62 | if (Team < Team.Spectators || Team > Team.Blue) 63 | failedOn = nameof(Team); 64 | 65 | return unpacker.Error; 66 | } 67 | 68 | public void Validate(int maxClients, ref string failedOn) 69 | { 70 | if (ClientID < 0 || ClientID >= maxClients) 71 | failedOn = nameof(ClientID); 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvEmoticon.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvEmoticon : BaseGameMessage, IClampedMaxClients 7 | { 8 | public override GameMessage Type => GameMessage.ServerEmoticon; 9 | 10 | public int ClientId { get; set; } 11 | public Emoticon Emoticon { get; set; } 12 | 13 | public override bool PackError(MsgPacker packer) 14 | { 15 | packer.AddInt(ClientId); 16 | packer.AddInt((int) Emoticon); 17 | return packer.Error; 18 | } 19 | 20 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 21 | { 22 | ClientId = unpacker.GetInt(); 23 | Emoticon = (Emoticon) unpacker.GetInt(); 24 | 25 | if (ClientId < 0) 26 | failedOn = nameof(ClientId); 27 | 28 | if (Emoticon < 0 || Emoticon >= Emoticon.NumEmoticons) 29 | failedOn = nameof(Emoticon); 30 | 31 | return unpacker.Error; 32 | } 33 | 34 | public void Validate(int maxClients, ref string failedOn) 35 | { 36 | if (ClientId < 0 || ClientId >= maxClients) 37 | failedOn = nameof(ClientId); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvExtraProjectile.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvExtraProjectile : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ServerExtraProjectile; 9 | 10 | public override bool PackError(MsgPacker packer) 11 | { 12 | return packer.Error; 13 | } 14 | 15 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 16 | { 17 | return unpacker.Error; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvGameInfo.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvGameInfo : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ServerGameInfo; 9 | 10 | public GameFlags GameFlags { get; set; } 11 | public int ScoreLimit { get; set; } 12 | public int TimeLimit { get; set; } 13 | public int MatchNum { get; set; } 14 | public int MatchCurrent { get; set; } 15 | 16 | public override bool PackError(MsgPacker packer) 17 | { 18 | packer.AddInt((int) GameFlags); 19 | packer.AddInt(ScoreLimit); 20 | packer.AddInt(TimeLimit); 21 | packer.AddInt(MatchNum); 22 | packer.AddInt(MatchCurrent); 23 | return packer.Error; 24 | } 25 | 26 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 27 | { 28 | GameFlags = (GameFlags) unpacker.GetInt(); 29 | ScoreLimit = unpacker.GetInt(); 30 | TimeLimit = unpacker.GetInt(); 31 | MatchNum = unpacker.GetInt(); 32 | MatchCurrent = unpacker.GetInt(); 33 | 34 | if (GameFlags < 0) 35 | failedOn = nameof(GameFlags); 36 | if (ScoreLimit < 0) 37 | failedOn = nameof(ScoreLimit); 38 | if (TimeLimit < 0) 39 | failedOn = nameof(TimeLimit); 40 | if (MatchNum < 0) 41 | failedOn = nameof(MatchNum); 42 | if (MatchCurrent < 0) 43 | failedOn = nameof(MatchCurrent); 44 | 45 | return unpacker.Error; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvGameMsg.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvGameMsg : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ServerGameMessage; 9 | 10 | public GameplayMessage Message { get; set; } 11 | public int? Param1 { get; set; } 12 | public int? Param2 { get; set; } 13 | public int? Param3 { get; set; } 14 | 15 | public override bool PackError(MsgPacker packer) 16 | { 17 | packer.AddInt((int) Message); 18 | if (Param1.HasValue) 19 | packer.AddInt(Param1.Value); 20 | if (Param2.HasValue) 21 | packer.AddInt(Param2.Value); 22 | if (Param3.HasValue) 23 | packer.AddInt(Param3.Value); 24 | return packer.Error; 25 | } 26 | 27 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 28 | { 29 | return unpacker.Error; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvKillMsg.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvKillMsg : BaseGameMessage, IClampedMaxClients 7 | { 8 | public override GameMessage Type => GameMessage.ServerKillMessage; 9 | 10 | public int Killer { get; set; } 11 | public int Victim { get; set; } 12 | public int Weapon { get; set; } 13 | public int ModeSpecial { get; set; } 14 | 15 | public override bool PackError(MsgPacker packer) 16 | { 17 | packer.AddInt(Killer); 18 | packer.AddInt(Victim); 19 | packer.AddInt(Weapon); 20 | packer.AddInt(ModeSpecial); 21 | return packer.Error; 22 | } 23 | 24 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 25 | { 26 | Killer = unpacker.GetInt(); 27 | Victim = unpacker.GetInt(); 28 | Weapon = unpacker.GetInt(); 29 | ModeSpecial = unpacker.GetInt(); 30 | 31 | if (Killer < 0) 32 | failedOn = nameof(Killer); 33 | if (Victim < 0) 34 | failedOn = nameof(Victim); 35 | if (Weapon < -3 || Weapon >= (int) Enums.Weapon.NumWeapons) 36 | failedOn = nameof(Weapon); 37 | 38 | return unpacker.Error; 39 | } 40 | 41 | public void Validate(int maxClients, ref string failedOn) 42 | { 43 | if (Killer < 0 || Killer >= maxClients) 44 | failedOn = nameof(Killer); 45 | if (Victim < 0 || Victim >= maxClients) 46 | failedOn = nameof(Victim); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvMotd.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvMotd : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ServerMotd; 9 | 10 | public string Message { get; set; } 11 | 12 | public override bool PackError(MsgPacker packer) 13 | { 14 | packer.AddString(Message); 15 | return packer.Error; 16 | } 17 | 18 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 19 | { 20 | Message = unpacker.GetString(Sanitize); 21 | return unpacker.Error; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvReadyToEnter.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvReadyToEnter : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ServerReadyToEnter; 9 | 10 | public override bool PackError(MsgPacker packer) 11 | { 12 | return packer.Error; 13 | } 14 | 15 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 16 | { 17 | return unpacker.Error; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvSettings.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvSettings : BaseGameMessage, IClampedMaxClients 7 | { 8 | public override GameMessage Type => GameMessage.ServerSettings; 9 | 10 | public bool KickVote { get; set; } 11 | public int KickMin { get; set; } 12 | public bool SpectatorsVote { get; set; } 13 | public bool TeamLock { get; set; } 14 | public bool TeamBalance { get; set; } 15 | public int PlayerSlots { get; set; } 16 | 17 | public override bool PackError(MsgPacker packer) 18 | { 19 | packer.AddBool(KickVote); 20 | packer.AddInt(KickMin); 21 | packer.AddBool(SpectatorsVote); 22 | packer.AddBool(TeamLock); 23 | packer.AddBool(TeamBalance); 24 | packer.AddInt(PlayerSlots); 25 | return packer.Error; 26 | } 27 | 28 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 29 | { 30 | KickVote = unpacker.GetBool(); 31 | KickMin = unpacker.GetInt(); 32 | SpectatorsVote = unpacker.GetBool(); 33 | TeamLock = unpacker.GetBool(); 34 | TeamBalance = unpacker.GetBool(); 35 | PlayerSlots = unpacker.GetInt(); 36 | return unpacker.Error; 37 | } 38 | 39 | public void Validate(int maxClients, ref string failedOn) 40 | { 41 | if (KickMin < 0 || KickMin > maxClients) 42 | failedOn = nameof(KickMin); 43 | 44 | if (PlayerSlots < 0 || PlayerSlots > maxClients) 45 | failedOn = nameof(PlayerSlots); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvTeam.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvTeam : BaseGameMessage, IClampedMaxClients 7 | { 8 | public override GameMessage Type => GameMessage.ServerTeam; 9 | 10 | public int ClientId { get; set; } 11 | public Team Team { get; set; } 12 | public bool Silent { get; set; } 13 | public int CooldownTick { get; set; } 14 | 15 | public override bool PackError(MsgPacker packer) 16 | { 17 | packer.AddInt(ClientId); 18 | packer.AddInt((int) Team); 19 | packer.AddBool(Silent); 20 | packer.AddInt(CooldownTick); 21 | return packer.Error; 22 | } 23 | 24 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 25 | { 26 | ClientId = unpacker.GetInt(); 27 | Team = (Team) unpacker.GetInt(); 28 | Silent = unpacker.GetBool(); 29 | CooldownTick = unpacker.GetInt(); 30 | 31 | if (Team < Team.Spectators || Team > Team.Blue) 32 | failedOn = nameof(Team); 33 | if (CooldownTick < 0) 34 | failedOn = nameof(CooldownTick); 35 | 36 | return unpacker.Error; 37 | } 38 | 39 | public void Validate(int maxClients, ref string failedOn) 40 | { 41 | if (ClientId < -1 || ClientId >= maxClients) 42 | failedOn = nameof(ClientId); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvTuneParams.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvTuneParams : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ServerTuneParams; 9 | 10 | public override bool PackError(MsgPacker packer) 11 | { 12 | return packer.Error; 13 | } 14 | 15 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 16 | { 17 | return unpacker.Error; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvVoteClearOptions.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvVoteClearOptions : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ServerVoteClearOptions; 9 | 10 | public override bool PackError(MsgPacker packer) 11 | { 12 | return packer.Error; 13 | } 14 | 15 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 16 | { 17 | return unpacker.Error; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvVoteOptionAdd.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvVoteOptionAdd : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ServerVoteOptionAdd; 9 | 10 | public string Description { get; set; } 11 | 12 | public override bool PackError(MsgPacker packer) 13 | { 14 | packer.AddString(Description); 15 | return packer.Error; 16 | } 17 | 18 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 19 | { 20 | Description = unpacker.GetString(Sanitize); 21 | return unpacker.Error; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvVoteOptionListAdd.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvVoteOptionListAdd : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ServerVoteOptionListAdd; 9 | 10 | public override bool PackError(MsgPacker packer) 11 | { 12 | return packer.Error; 13 | } 14 | 15 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 16 | { 17 | return unpacker.Error; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvVoteOptionRemove.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvVoteOptionRemove : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ServerVoteOptionRemove; 9 | 10 | public string Description { get; set; } 11 | 12 | public override bool PackError(MsgPacker packer) 13 | { 14 | packer.AddString(Description); 15 | return packer.Error; 16 | } 17 | 18 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 19 | { 20 | Description = unpacker.GetString(Sanitize); 21 | return unpacker.Error; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvVoteSet.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvVoteSet : BaseGameMessage, IClampedMaxClients 7 | { 8 | public override GameMessage Type => GameMessage.ServerVoteSet; 9 | 10 | public int ClientID { get; set; } 11 | public Vote VoteType { get; set; } 12 | public int Timeout { get; set; } 13 | public string Description { get; set; } 14 | public string Reason { get; set; } 15 | 16 | public override bool PackError(MsgPacker packer) 17 | { 18 | packer.AddInt(ClientID); 19 | packer.AddInt((int) VoteType); 20 | packer.AddInt(Timeout); 21 | packer.AddString(Description); 22 | packer.AddString(Reason); 23 | return packer.Error; 24 | } 25 | 26 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 27 | { 28 | ClientID = unpacker.GetInt(); 29 | VoteType = (Vote) unpacker.GetInt(); 30 | Timeout = unpacker.GetInt(); 31 | Description = unpacker.GetString(Sanitize); 32 | Reason = unpacker.GetString(Sanitize); 33 | 34 | if (VoteType < 0 || VoteType >= Vote.NumTypes) 35 | failedOn = nameof(VoteType); 36 | if (Timeout < 0 || Timeout > 60) 37 | failedOn = nameof(Timeout); 38 | 39 | return unpacker.Error; 40 | } 41 | 42 | public void Validate(int maxClients, ref string failedOn) 43 | { 44 | if (ClientID < -1 || ClientID >= maxClients) 45 | failedOn = nameof(ClientID); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvVoteStatus.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvVoteStatus : BaseGameMessage, IClampedMaxClients 7 | { 8 | public override GameMessage Type => GameMessage.ServerVoteStatus; 9 | 10 | public int Yes { get; set; } 11 | public int No { get; set; } 12 | public int Pass { get; set; } 13 | public int Total { get; set; } 14 | 15 | public override bool PackError(MsgPacker packer) 16 | { 17 | packer.AddInt(Yes); 18 | packer.AddInt(No); 19 | packer.AddInt(Pass); 20 | packer.AddInt(Total); 21 | return packer.Error; 22 | } 23 | 24 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 25 | { 26 | Yes = unpacker.GetInt(); 27 | No = unpacker.GetInt(); 28 | Pass = unpacker.GetInt(); 29 | Total = unpacker.GetInt(); 30 | return unpacker.Error; 31 | } 32 | 33 | public void Validate(int maxClients, ref string failedOn) 34 | { 35 | if (Yes < 0 || Yes > maxClients) 36 | failedOn = nameof(Yes); 37 | if (No < 0 || No > maxClients) 38 | failedOn = nameof(No); 39 | if (Pass < 0 || Pass > maxClients) 40 | failedOn = nameof(Pass); 41 | if (Total < 0 || Total > maxClients) 42 | failedOn = nameof(Total); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/messages/GameMsg_SvWeaponPickup.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Common.Protocol 5 | { 6 | public class GameMsg_SvWeaponPickup : BaseGameMessage 7 | { 8 | public override GameMessage Type => GameMessage.ServerWeaponPickup; 9 | 10 | public Weapon Weapon { get; set; } 11 | 12 | public override bool PackError(MsgPacker packer) 13 | { 14 | packer.AddInt((int) Weapon); 15 | return packer.Error; 16 | } 17 | 18 | public override bool UnPackError(UnPacker unpacker, ref string failedOn) 19 | { 20 | Weapon = (Weapon) unpacker.GetInt(); 21 | 22 | if (Weapon < 0 || Weapon >= Weapon.NumWeapons) 23 | failedOn = nameof(Weapon); 24 | 25 | return unpacker.Error; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/snapshot_items/SnapshotCharacter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using TeeSharp.Common.Enums; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public class SnapshotCharacter : SnapshotCharacterCore, IEquatable 9 | { 10 | public override SnapshotItems Type => SnapshotItems.Character; 11 | 12 | [MarshalAs(UnmanagedType.I4)] public int Health; 13 | [MarshalAs(UnmanagedType.I4)] public int Armor; 14 | [MarshalAs(UnmanagedType.I4)] public int AmmoCount; 15 | [MarshalAs(UnmanagedType.I4)] public Weapon Weapon; 16 | [MarshalAs(UnmanagedType.I4)] public Emote Emote; 17 | [MarshalAs(UnmanagedType.I4)] public int AttackTick; 18 | [MarshalAs(UnmanagedType.I4)] public CoreEvents TriggeredEvents; 19 | 20 | public bool Equals(SnapshotCharacter other) 21 | { 22 | if (ReferenceEquals(null, other)) return false; 23 | if (ReferenceEquals(this, other)) return true; 24 | return base.Equals(other) && 25 | Health == other.Health && 26 | Armor == other.Armor && 27 | AmmoCount == other.AmmoCount && 28 | Weapon == other.Weapon && 29 | Emote == other.Emote && 30 | AttackTick == other.AttackTick && 31 | TriggeredEvents == other.TriggeredEvents; 32 | } 33 | 34 | public override bool Equals(object obj) 35 | { 36 | if (ReferenceEquals(null, obj)) return false; 37 | if (ReferenceEquals(this, obj)) return true; 38 | if (obj.GetType() != this.GetType()) return false; 39 | return Equals((SnapshotCharacter) obj); 40 | } 41 | 42 | public override int GetHashCode() 43 | { 44 | unchecked 45 | { 46 | var hashCode = base.GetHashCode(); 47 | hashCode = (hashCode * 397) ^ Health; 48 | hashCode = (hashCode * 397) ^ Armor; 49 | hashCode = (hashCode * 397) ^ AmmoCount; 50 | hashCode = (hashCode * 397) ^ (int) Weapon; 51 | hashCode = (hashCode * 397) ^ (int) Emote; 52 | hashCode = (hashCode * 397) ^ AttackTick; 53 | hashCode = (hashCode * 397) ^ (int) TriggeredEvents; 54 | return hashCode; 55 | } 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/snapshot_items/SnapshotDemoGameInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | using TeeSharp.Common.Snapshots; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public class SnapshotDemoGameInfo : BaseSnapshotItem 9 | { 10 | public override SnapshotItems Type => SnapshotItems.DemoGameInfo; 11 | 12 | [MarshalAs(UnmanagedType.I4)] public GameFlags GameFlags; 13 | [MarshalAs(UnmanagedType.I4)] public int ScoreLimit; 14 | [MarshalAs(UnmanagedType.I4)] public int TimeLimit; 15 | [MarshalAs(UnmanagedType.I4)] public int MatchNum; 16 | [MarshalAs(UnmanagedType.I4)] public int MatchCurrent; 17 | } 18 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/snapshot_items/SnapshotDemoTuneParams.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | using TeeSharp.Common.Snapshots; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public class SnapshotDemoTuneParams : BaseSnapshotItem 9 | { 10 | public override SnapshotItems Type => SnapshotItems.DemoTuneParams; 11 | 12 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public int[] TuneParams; 13 | } 14 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/snapshot_items/SnapshotEventDamage.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | using TeeSharp.Common.Snapshots; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public class SnapshotEventDamage : BaseSnapshotEvent 9 | { 10 | public override SnapshotItems Type => SnapshotItems.EventDamage; 11 | 12 | public bool IsSelf 13 | { 14 | get => Self != 0; 15 | set => Self = value ? 1 : 0; 16 | } 17 | 18 | [MarshalAs(UnmanagedType.I4)] public int ClientId; 19 | [MarshalAs(UnmanagedType.I4)] public int Angle; 20 | [MarshalAs(UnmanagedType.I4)] public int HealthAmount; 21 | [MarshalAs(UnmanagedType.I4)] public int ArmorAmount; 22 | [MarshalAs(UnmanagedType.I4)] public int Self; 23 | } 24 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/snapshot_items/SnapshotEventDeath.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | using TeeSharp.Common.Snapshots; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public class SnapshotEventDeath : BaseSnapshotEvent 9 | { 10 | public override SnapshotItems Type => SnapshotItems.EventDeath; 11 | 12 | [MarshalAs(UnmanagedType.I4)] public int ClientId; 13 | } 14 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/snapshot_items/SnapshotEventExplosion.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | using TeeSharp.Common.Snapshots; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public class SnapshotEventExplosion : BaseSnapshotEvent 9 | { 10 | public override SnapshotItems Type => SnapshotItems.EventExplosion; 11 | } 12 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/snapshot_items/SnapshotEventHammerHit.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | using TeeSharp.Common.Snapshots; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public class SnapshotEventHammerHit : BaseSnapshotEvent 9 | { 10 | public override SnapshotItems Type => SnapshotItems.EventHammerHit; 11 | } 12 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/snapshot_items/SnapshotEventSoundWorld.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | using TeeSharp.Common.Snapshots; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public class SnapshotEventSoundWorld : BaseSnapshotEvent 9 | { 10 | public override SnapshotItems Type => SnapshotItems.EventSoundWorld; 11 | 12 | [MarshalAs(UnmanagedType.I4)] public Sound Sound; 13 | } 14 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/snapshot_items/SnapshotEventSpawn.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | using TeeSharp.Common.Snapshots; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public class SnapshotEventSpawn : BaseSnapshotEvent 9 | { 10 | public override SnapshotItems Type => SnapshotItems.EventSpawn; 11 | } 12 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/snapshot_items/SnapshotFlag.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | using TeeSharp.Common.Snapshots; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public class SnapshotFlag : BaseSnapshotItem 9 | { 10 | public override SnapshotItems Type => SnapshotItems.Flag; 11 | 12 | [MarshalAs(UnmanagedType.I4)] public int X; 13 | [MarshalAs(UnmanagedType.I4)] public int Y; 14 | [MarshalAs(UnmanagedType.I4)] public Team Team; 15 | } 16 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/snapshot_items/SnapshotGameData.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | using TeeSharp.Common.Snapshots; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public class SnapshotGameData : BaseSnapshotItem 9 | { 10 | public override SnapshotItems Type => SnapshotItems.GameData; 11 | 12 | [MarshalAs(UnmanagedType.I4)] public int GameStartTick; 13 | [MarshalAs(UnmanagedType.I4)] public GameStateFlags GameStateFlags; 14 | [MarshalAs(UnmanagedType.I4)] public int GameStateEndTick; 15 | } 16 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/snapshot_items/SnapshotGameDataFlag.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | using TeeSharp.Common.Snapshots; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public class SnapshotGameDataFlag : BaseSnapshotItem 9 | { 10 | public override SnapshotItems Type => SnapshotItems.GameDataFlag; 11 | 12 | [MarshalAs(UnmanagedType.I4)] public int FlagCarrierRed; 13 | [MarshalAs(UnmanagedType.I4)] public int FlagCarrierBlue; 14 | [MarshalAs(UnmanagedType.I4)] public int FlagDropTickRed; 15 | [MarshalAs(UnmanagedType.I4)] public int FlagDropTickBlue; 16 | } 17 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/snapshot_items/SnapshotGameDataTeam.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | using TeeSharp.Common.Snapshots; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public class SnapshotGameDataTeam : BaseSnapshotItem 9 | { 10 | public override SnapshotItems Type => SnapshotItems.GameDataTeam; 11 | 12 | [MarshalAs(UnmanagedType.I4)] public int ScoreRed; 13 | [MarshalAs(UnmanagedType.I4)] public int ScoreBlue; 14 | } 15 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/snapshot_items/SnapshotLaser.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | using TeeSharp.Common.Snapshots; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public class SnapshotLaser : BaseSnapshotItem 9 | { 10 | public override SnapshotItems Type => SnapshotItems.Laser; 11 | 12 | [MarshalAs(UnmanagedType.I4)] public int X; 13 | [MarshalAs(UnmanagedType.I4)] public int Y; 14 | [MarshalAs(UnmanagedType.I4)] public int FromX; 15 | [MarshalAs(UnmanagedType.I4)] public int FromY; 16 | [MarshalAs(UnmanagedType.I4)] public int StartTick; 17 | } 18 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/snapshot_items/SnapshotPickup.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | using TeeSharp.Common.Snapshots; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public class SnapshotPickup : BaseSnapshotItem 9 | { 10 | public override SnapshotItems Type => SnapshotItems.Pickup; 11 | 12 | [MarshalAs(UnmanagedType.I4)] public int X; 13 | [MarshalAs(UnmanagedType.I4)] public int Y; 14 | [MarshalAs(UnmanagedType.I4)] public Pickup Pickup; 15 | } 16 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/snapshot_items/SnapshotPlayerInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | using TeeSharp.Common.Snapshots; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public class SnapshotPlayerInfo : BaseSnapshotItem 9 | { 10 | public override SnapshotItems Type => SnapshotItems.PlayerInfo; 11 | 12 | [MarshalAs(UnmanagedType.I4)] public PlayerFlags PlayerFlags; 13 | [MarshalAs(UnmanagedType.I4)] public int Score; 14 | [MarshalAs(UnmanagedType.I4)] public int Latency; 15 | } 16 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/snapshot_items/SnapshotProjectile.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | using TeeSharp.Common.Snapshots; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public class SnapshotProjectile : BaseSnapshotItem 9 | { 10 | public override SnapshotItems Type => SnapshotItems.Projectile; 11 | 12 | [MarshalAs(UnmanagedType.I4)] public int X; 13 | [MarshalAs(UnmanagedType.I4)] public int Y; 14 | [MarshalAs(UnmanagedType.I4)] public int VelX; 15 | [MarshalAs(UnmanagedType.I4)] public int VelY; 16 | [MarshalAs(UnmanagedType.I4)] public Weapon Weapon; 17 | [MarshalAs(UnmanagedType.I4)] public int StartTick; 18 | } 19 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Protocol/snapshot_items/SnapshotSpectatorInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | using TeeSharp.Common.Snapshots; 4 | 5 | namespace TeeSharp.Common.Protocol 6 | { 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public class SnapshotSpectatorInfo : BaseSnapshotItem 9 | { 10 | public override SnapshotItems Type => SnapshotItems.SpectatorInfo; 11 | 12 | [MarshalAs(UnmanagedType.I4)] public SpectatorMode SpectatorMode; 13 | [MarshalAs(UnmanagedType.I4)] public int SpectatorId; 14 | [MarshalAs(UnmanagedType.I4)] public int X; 15 | [MarshalAs(UnmanagedType.I4)] public int Y; 16 | } 17 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Snapshots/Snapshot.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | using TeeSharp.Core; 3 | 4 | namespace TeeSharp.Common.Snapshots 5 | { 6 | public class Snapshot 7 | { 8 | public const int MaxParts = 64; 9 | public const int MaxSize = MaxParts * 1024; 10 | public const int MaxPacketSize = 900; 11 | 12 | public SnapshotItem this[int index] => _items[index]; 13 | 14 | public readonly int Size; 15 | public int ItemsCount => _items.Length; 16 | 17 | private SnapshotItem[] _items; 18 | 19 | public Snapshot(SnapshotItem[] items, int size) 20 | { 21 | Size = size; 22 | _items = items; 23 | } 24 | 25 | public static SnapshotItems Type(int key) 26 | { 27 | return (SnapshotItems) (key >> 16); 28 | } 29 | 30 | public static int Id(int key) 31 | { 32 | return key & 0b_11111111_11111111; 33 | } 34 | 35 | public static int Key(int id, SnapshotItems type) 36 | { 37 | return (int) type << 16 | id; 38 | } 39 | 40 | public int Crc() 41 | { 42 | int crc = 0; 43 | 44 | for (var i = 0; i < _items.Length; i++) 45 | { 46 | var data = _items[i].Item.ToArray(); 47 | for (var field = 0; field < data.Length; field++) 48 | { 49 | crc += data[field]; 50 | } 51 | } 52 | 53 | return crc; 54 | } 55 | 56 | public void DebugDump() 57 | { 58 | Debug.Log("snapshot", $"data_size={Size} num_items={ItemsCount}"); 59 | for (var i = 0; i < _items.Length; i++) 60 | { 61 | Debug.Log("snapshot", $"type={_items[i].Item.Type} id={_items[i].Id}"); 62 | var data = _items[i].Item.ToArray(); 63 | for (var field = 0; field < data.Length; field++) 64 | Debug.Log("snapshot", $"field={field} value={data[field]}"); 65 | } 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Snapshots/SnapshotBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using TeeSharp.Core; 4 | 5 | namespace TeeSharp.Common.Snapshots 6 | { 7 | public class SnapshotBuilder 8 | { 9 | public const int MaxItems = 1024; 10 | 11 | protected virtual IList SnapshotItems { get; set; } 12 | protected virtual int SnapshotSize { get; set; } 13 | 14 | public SnapshotBuilder() 15 | { 16 | SnapshotItems = new List(MaxItems); 17 | SnapshotSize = 0; 18 | } 19 | 20 | public void Start() 21 | { 22 | SnapshotItems.Clear(); 23 | SnapshotSize = 0; 24 | } 25 | 26 | public Snapshot Finish() 27 | { 28 | return new Snapshot(SnapshotItems.ToArray(), SnapshotSize); 29 | } 30 | 31 | public SnapshotItem FindItem(int key) 32 | { 33 | for (var i = 0; i < SnapshotItems.Count; i++) 34 | { 35 | if (SnapshotItems[i].Key == key) 36 | return SnapshotItems[i]; 37 | } 38 | return null; 39 | } 40 | 41 | public bool AddItem(BaseSnapshotItem obj, int id) 42 | { 43 | if (obj == null) 44 | { 45 | Debug.Warning("snapshots", "add null object"); 46 | return false; 47 | } 48 | 49 | if (SnapshotItems.Count + 1 >= MaxItems) 50 | { 51 | Debug.Warning("snapshots", "too many items"); 52 | return false; 53 | } 54 | 55 | var itemSize = SnapshotItemsInfo.GetSize(obj.GetType()); 56 | if (SnapshotSize + itemSize >= Snapshot.MaxSize) 57 | { 58 | Debug.Warning("snapshots", "too much data"); 59 | return false; 60 | } 61 | 62 | var item = new SnapshotItem(id, obj); 63 | SnapshotSize += itemSize; 64 | SnapshotItems.Add(item); 65 | return true; 66 | } 67 | 68 | public T NewItem(int id) where T : BaseSnapshotItem, new() 69 | { 70 | if (SnapshotItems.Count + 1 >= MaxItems) 71 | { 72 | Debug.Warning("snapshots", "too many items"); 73 | return null; 74 | } 75 | 76 | var itemSize = SnapshotItemsInfo.GetSize(); 77 | 78 | if (SnapshotSize + itemSize >= Snapshot.MaxSize) 79 | { 80 | Debug.Warning("snapshots", "too much data"); 81 | return null; 82 | } 83 | 84 | var item = new SnapshotItem(id, new T()); 85 | SnapshotSize += itemSize; 86 | SnapshotItems.Add(item); 87 | return (T) item.Item; 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Snapshots/SnapshotInfo.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Snapshots 2 | { 3 | public struct SnapshotInfo 4 | { 5 | public long TagTime { get; set; } 6 | public int Tick { get; set; } 7 | public Snapshot Snapshot { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Snapshots/SnapshotItem.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common.Snapshots 2 | { 3 | public class SnapshotItem 4 | { 5 | public readonly int Id; 6 | public readonly int Key; 7 | public readonly BaseSnapshotItem Item; 8 | 9 | // TODO make cached serialize 10 | public SnapshotItem(int id, BaseSnapshotItem item) 11 | { 12 | Key = Snapshot.Key(id, item.Type); 13 | Id = id; 14 | Item = item; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Snapshots/SnapshotItemsInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using TeeSharp.Common.Enums; 5 | 6 | namespace TeeSharp.Common.Snapshots 7 | { 8 | public static class SnapshotItemsInfo 9 | { 10 | private static readonly Dictionary _sizes; 11 | 12 | static SnapshotItemsInfo() 13 | { 14 | _sizes = new Dictionary((int) SnapshotItems.NumItems); 15 | } 16 | 17 | public static int GetSize(Type type) 18 | { 19 | if (_sizes.ContainsKey(type)) 20 | return _sizes[type]; 21 | 22 | var size = Marshal.SizeOf(type); 23 | _sizes.Add(type, size); 24 | return size; 25 | } 26 | 27 | public static int GetSize() where T : BaseSnapshotItem 28 | { 29 | return GetSize(typeof(T)); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Snapshots/SnapshotStorage.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TeeSharp.Common.Snapshots 4 | { 5 | public class SnapshotStorage 6 | { 7 | protected IList SnapshotInfos { get; set; } 8 | 9 | public SnapshotStorage() 10 | { 11 | SnapshotInfos = new List(); 12 | } 13 | 14 | public void PurgeUntil(int tick) 15 | { 16 | for (var i = 0; i < SnapshotInfos.Count; i++) 17 | { 18 | if (SnapshotInfos[i].Tick >= tick) 19 | return; 20 | 21 | SnapshotInfos.RemoveAt(i--); 22 | } 23 | } 24 | 25 | public void Add(int tick, long tagTime, Snapshot snapshot) 26 | { 27 | SnapshotInfos.Add(new SnapshotInfo 28 | { 29 | Tick = tick, 30 | TagTime = tagTime, 31 | Snapshot = snapshot, 32 | }); 33 | } 34 | 35 | public bool Get(int tick, out long tagTime, out Snapshot snapshot) 36 | { 37 | for (var i = 0; i < SnapshotInfos.Count; i++) 38 | { 39 | if (SnapshotInfos[i].Tick == tick) 40 | { 41 | tagTime = SnapshotInfos[i].TagTime; 42 | snapshot = SnapshotInfos[i].Snapshot; 43 | return true; 44 | } 45 | } 46 | tagTime = -1; 47 | snapshot = null; 48 | return false; 49 | } 50 | 51 | public void PurgeAll() 52 | { 53 | SnapshotInfos.Clear(); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Snapshots/abstract/BaseSnapshotEvent.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | 4 | namespace TeeSharp.Common.Snapshots 5 | { 6 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 7 | public abstract class BaseSnapshotEvent : BaseSnapshotItem 8 | { 9 | public override SnapshotItems Type => SnapshotItems.EventCommon; 10 | 11 | [MarshalAs(UnmanagedType.I4)] public int X; 12 | [MarshalAs(UnmanagedType.I4)] public int Y; 13 | } 14 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Snapshots/abstract/BaseSnapshotItem.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using TeeSharp.Common.Enums; 3 | 4 | namespace TeeSharp.Common.Snapshots 5 | { 6 | // TODO make snapshot item immutable 7 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 8 | public abstract class BaseSnapshotItem 9 | { 10 | public abstract SnapshotItems Type { get; } 11 | 12 | public static T FromArray(int[] array) where T : BaseSnapshotItem, new() 13 | { 14 | var handle = GCHandle.Alloc(array, GCHandleType.Pinned); 15 | var ptr = handle.AddrOfPinnedObject(); 16 | 17 | var obj = Marshal.PtrToStructure(ptr); 18 | handle.Free(); 19 | 20 | return obj; 21 | } 22 | 23 | public int[] ToArray() 24 | { 25 | var array = new int[SnapshotItemsInfo.GetSize(GetType()) / sizeof(int)]; 26 | var handle = GCHandle.Alloc(array, GCHandleType.Pinned); 27 | var ptr = handle.AddrOfPinnedObject(); 28 | 29 | Marshal.StructureToPtr(this, ptr, false); 30 | handle.Free(); 31 | 32 | return array; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Storage/abstract/BaseStorage.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using TeeSharp.Core; 3 | 4 | namespace TeeSharp.Common.Storage 5 | { 6 | public enum StorageType 7 | { 8 | Basic = 0, 9 | Server = 1, 10 | Client = 2 11 | } 12 | 13 | public abstract class BaseStorage : BaseInterface 14 | { 15 | public const string UserDir = "$USERDIR"; 16 | public const string DataDir = "$DATADIR"; 17 | public const string CurrentDir = "$CURRENTDIR"; 18 | 19 | public const int TypeSave = 0; 20 | public const int TypeAll = -1; 21 | 22 | public abstract bool Init(string appName, StorageType storageType); 23 | public abstract FileStream OpenFile(string fileName, FileAccess fileAccess, int pathIndex = -1); 24 | 25 | protected abstract string GetPath(int pathIndex, string fileName); 26 | protected abstract void LoadPaths(); 27 | protected abstract void AddPath(string path); 28 | 29 | protected virtual void AddDefaultPaths() 30 | { 31 | AddPath(UserDir); 32 | AddPath(DataDir); 33 | AddPath(CurrentDir); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Tuning/TuningParameter.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Common 2 | { 3 | public class TuningParameter 4 | { 5 | public readonly int DefaultValue; 6 | 7 | public int Value { get; set; } 8 | 9 | public float FloatValue 10 | { 11 | get => Value / 100.00f; 12 | set => Value = (int) System.Math.Round(value * 100f); 13 | } 14 | 15 | public TuningParameter(float defaultValue) 16 | { 17 | DefaultValue = (int) System.Math.Round(defaultValue * 100f); 18 | Value = DefaultValue; 19 | } 20 | 21 | public static implicit operator float(TuningParameter v) 22 | { 23 | return v.FloatValue; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /TeeSharp.Common/src/Tuning/abstract/BaseTuningParams.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using TeeSharp.Core; 4 | 5 | namespace TeeSharp.Common 6 | { 7 | public abstract class BaseTuningParams : BaseInterface, IEnumerable> 8 | { 9 | public virtual TuningParameter this[string key] => Parameters[key]; 10 | public virtual int Count => Parameters.Count; 11 | 12 | protected virtual IDictionary Parameters { get; set; } 13 | 14 | public virtual bool Contains(string param) => Parameters.ContainsKey(param); 15 | public abstract void Reset(); 16 | public abstract IEnumerator> GetEnumerator(); 17 | 18 | protected abstract void AppendParameters(IDictionary parameters); 19 | 20 | IEnumerator IEnumerable.GetEnumerator() 21 | { 22 | return GetEnumerator(); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /TeeSharp.Core/TeeSharp.Core.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | 7.2 6 | TeeSharp.Core 7 | 1.0.0-alpha 8 | Matodor 9 | TeeSharp is implementation of Teeworlds in .NET 10 | TeeSharp.Core 11 | false 12 | First release 13 | tee teeworlds teesharp 14 | https://github.com/Matodor/TeeSharp 15 | https://github.com/Matodor/TeeSharp/raw/master/res/TeeSharp.png 16 | https://github.com/Matodor/TeeSharp 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /TeeSharp.Core/src/BidirectionalList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | namespace TeeSharp.Core 6 | { 7 | public class BidirectionalList : IEnumerable 8 | { 9 | public class Node 10 | { 11 | public Node Prev { get; set; } 12 | public Node Next { get; set; } 13 | public T Value { get; set; } 14 | } 15 | 16 | public Node First { get; private set; } 17 | public Node Last { get; private set; } 18 | public int Count { get; private set; } 19 | 20 | private Node _nextTraverseEntity; 21 | 22 | private BidirectionalList() 23 | { 24 | Last = First = null; 25 | Count = 0; 26 | } 27 | 28 | public static BidirectionalList New() 29 | { 30 | return new BidirectionalList(); 31 | } 32 | 33 | public Node Add(T item) 34 | { 35 | var node = new Node() 36 | { 37 | Value = item, 38 | Next = First, 39 | Prev = null 40 | }; 41 | 42 | if (First != null) 43 | First.Prev = node; 44 | 45 | if (Last == null) 46 | Last = node; 47 | 48 | First = node; 49 | Count++; 50 | 51 | return node; 52 | } 53 | 54 | public void RemoveFast(Node node) 55 | { 56 | if (node == null) 57 | throw new ArgumentNullException(nameof(node)); 58 | 59 | if (node.Prev != null) 60 | node.Prev.Next = node.Next; 61 | else 62 | First = node.Next; // remove head 63 | 64 | if (node.Next != null) 65 | node.Next.Prev = node.Prev; 66 | else 67 | Last = node.Prev; // remove last 68 | 69 | if (_nextTraverseEntity == node) 70 | _nextTraverseEntity = node.Next; 71 | 72 | node.Next = null; 73 | node.Prev = null; 74 | 75 | Count--; 76 | } 77 | 78 | public IEnumerator GetEnumerator() 79 | { 80 | var current = First; 81 | while (current != null) 82 | { 83 | _nextTraverseEntity = current.Next; 84 | yield return current.Value; 85 | current = _nextTraverseEntity; 86 | } 87 | } 88 | 89 | IEnumerator IEnumerable.GetEnumerator() 90 | { 91 | return GetEnumerator(); 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /TeeSharp.Core/src/Debug/Debug.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TeeSharp.Core 4 | { 5 | public static class Debug 6 | { 7 | public static ILogger Logger { get; set; } = new Logger(); 8 | 9 | public static void Assert(bool condition, string error) 10 | { 11 | if (!condition) 12 | Assert("assert", error); 13 | } 14 | 15 | public static void Log(string sys, string format) 16 | { 17 | Logger.LogFormat(LogType.Log, $"[{sys}] {format}"); 18 | } 19 | 20 | public static void Error(string sys, string format) 21 | { 22 | Logger.LogFormat(LogType.Error, $"[{sys}] {format}"); 23 | } 24 | 25 | public static void Assert(string sys, string format) 26 | { 27 | Logger.LogFormat(LogType.Assert, $"[{sys}] {format}"); 28 | } 29 | 30 | public static void Warning(string sys, string format) 31 | { 32 | Logger.LogFormat(LogType.Warning, $"[{sys}] {format}"); 33 | } 34 | 35 | public static void Exception(string sys, Exception exception) 36 | { 37 | Logger.LogFormat(LogType.Exception, $"[{sys}] {exception}"); 38 | } 39 | 40 | public static void Exception(string sys, string format) 41 | { 42 | Logger.LogFormat(LogType.Exception, $"[{sys}] {format}"); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /TeeSharp.Core/src/Debug/ILogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TeeSharp.Core 4 | { 5 | public enum LogType 6 | { 7 | Error = 0, 8 | Assert, 9 | Warning, 10 | Log, 11 | Exception, 12 | } 13 | 14 | public interface ILogger 15 | { 16 | ILoggerHandler Handler { get; set; } 17 | LogType FilterLogType { get; set; } 18 | bool LogEnabled { get; set; } 19 | 20 | void LogFormat(LogType logType, string format, params object[] args); 21 | void LogException(Exception exception); 22 | bool IsLogTypeAllowed(LogType logType); 23 | } 24 | } -------------------------------------------------------------------------------- /TeeSharp.Core/src/Debug/ILoggerHandler.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace TeeSharp.Core 4 | { 5 | public interface ILoggerHandler 6 | { 7 | TextWriter TextWriter { get; set; } 8 | 9 | void Write(string format); 10 | void WriteLine(string format); 11 | } 12 | } -------------------------------------------------------------------------------- /TeeSharp.Core/src/Debug/Logger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TeeSharp.Core 4 | { 5 | public class Logger : ILogger 6 | { 7 | public ILoggerHandler Handler { get; set; } = new LoggerHandler(); 8 | public LogType FilterLogType { get; set; } = LogType.Log; 9 | public bool LogEnabled { get; set; } = true; 10 | 11 | public Logger() 12 | { 13 | 14 | } 15 | 16 | public void LogFormat(LogType logType, string format, params object[] args) 17 | { 18 | if (!IsLogTypeAllowed(logType)) 19 | return; 20 | 21 | System.Console.ForegroundColor = System.ConsoleColor.DarkYellow; 22 | Handler.Write($"[{DateTime.Now:G}]"); 23 | 24 | switch (logType) 25 | { 26 | case LogType.Error: 27 | System.Console.ForegroundColor = System.ConsoleColor.Red; 28 | break; 29 | case LogType.Assert: 30 | System.Console.ForegroundColor = System.ConsoleColor.Green; 31 | break; 32 | case LogType.Warning: 33 | System.Console.ForegroundColor = System.ConsoleColor.Yellow; 34 | break; 35 | case LogType.Log: 36 | System.Console.ForegroundColor = System.ConsoleColor.Gray; 37 | break; 38 | case LogType.Exception: 39 | System.Console.ForegroundColor = System.ConsoleColor.Red; 40 | break; 41 | default: 42 | System.Console.ForegroundColor = System.ConsoleColor.Gray; 43 | break; 44 | } 45 | 46 | Handler.WriteLine(args == null || args.Length == 0 ? format : string.Format(format, args)); 47 | System.Console.ResetColor(); 48 | } 49 | 50 | public void LogException(Exception exception) 51 | { 52 | System.Console.ForegroundColor = System.ConsoleColor.Yellow; 53 | Handler.Write($"[{DateTime.Now:G}]"); 54 | System.Console.ForegroundColor = System.ConsoleColor.Red; 55 | Handler.WriteLine(exception.ToString()); 56 | System.Console.ResetColor(); 57 | } 58 | 59 | public bool IsLogTypeAllowed(LogType logType) 60 | { 61 | if (!LogEnabled) 62 | return false; 63 | if (logType == LogType.Exception) 64 | return true; 65 | if (FilterLogType != LogType.Exception) 66 | return logType <= FilterLogType; 67 | return false; 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /TeeSharp.Core/src/Debug/LoggerHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Text; 4 | 5 | namespace TeeSharp.Core 6 | { 7 | public class LoggerHandler : ILoggerHandler 8 | { 9 | public TextWriter TextWriter { get; set; } 10 | 11 | public LoggerHandler() 12 | { 13 | Console.OutputEncoding = Encoding.UTF8; 14 | TextWriter = System.Console.Out; 15 | } 16 | 17 | public void Write(string format) 18 | { 19 | TextWriter.Write(format); 20 | } 21 | 22 | public void WriteLine(string format) 23 | { 24 | TextWriter.WriteLine(format); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /TeeSharp.Core/src/Extensions/ArrayExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TeeSharp.Core.Extensions 4 | { 5 | public static class ArrayExtensions 6 | { 7 | public static bool ArrayCompare(this byte[] b1, byte[] compareArray) 8 | { 9 | return b1.Equals(compareArray) || b1.AsSpan().SequenceEqual(compareArray); 10 | } 11 | 12 | public static bool ArrayCompare(this byte[] b1, byte[] compareArray, int limit) 13 | { 14 | return b1.Equals(compareArray) || b1.AsSpan(0, limit).SequenceEqual(compareArray); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /TeeSharp.Core/src/IoC/ContainerExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | // https://github.com/microsoft/MinIoC/blob/master/Container.cs 4 | 5 | using System; 6 | 7 | namespace TeeSharp.Core.IoC 8 | { 9 | public static class ContainerExtensions 10 | { 11 | public static Container.IRegisteredType Register(this Container container, Type type) 12 | { 13 | return container.Register(typeof(T), type); 14 | } 15 | 16 | public static Container.IRegisteredType Register(this Container container) 17 | where TImplementation : TInterface 18 | { 19 | return container.Register(typeof(TInterface), typeof(TImplementation)); 20 | } 21 | 22 | public static Container.IRegisteredType Register(this Container container, Func factory) 23 | { 24 | return container.Register(typeof(T), () => factory()); 25 | } 26 | 27 | public static Container.IRegisteredType Register(this Container container) 28 | { 29 | return container.Register(typeof(T), typeof(T)); 30 | } 31 | 32 | public static T Resolve(this Container.IScope scope) 33 | { 34 | return (T) scope.GetService(typeof(T)); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /TeeSharp.Core/src/IoC/IServiceBinder.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Core.IoC 2 | { 3 | public interface IServiceBinder 4 | { 5 | void Bind(Container container); 6 | } 7 | } -------------------------------------------------------------------------------- /TeeSharp.Core/src/Kernel/BaseInterface.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Core 2 | { 3 | public abstract class BaseInterface 4 | { 5 | public static IKernel Kernel; 6 | } 7 | } -------------------------------------------------------------------------------- /TeeSharp.Core/src/Kernel/Binder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Reflection; 4 | 5 | namespace TeeSharp.Core 6 | { 7 | public abstract class Binder 8 | { 9 | public Type BindedType { get; } 10 | public Type InjectedType { get; protected set; } 11 | public Func Activator { get; protected set; } 12 | 13 | protected object Singleton { get; set; } 14 | 15 | protected Binder(Type bindedType) 16 | { 17 | Singleton = null; 18 | BindedType = bindedType; 19 | } 20 | } 21 | 22 | public class Binder : Binder 23 | { 24 | public Binder() : base(typeof(TBinded)) 25 | { 26 | Activator = () => throw new Exception($"Type '{typeof(TBinded).Name}' not binded"); 27 | } 28 | 29 | private void CheckInjectedType() 30 | { 31 | if (InjectedType == null) 32 | throw new NullReferenceException("Bind type first"); 33 | if (!InjectedType.IsClass) 34 | throw new Exception($"Injected type ({InjectedType.Name}) must be a class with public constructor without parameters"); 35 | } 36 | 37 | public void AsSingleton() 38 | { 39 | CheckInjectedType(); 40 | var activator = Activator; 41 | 42 | Activator = () => 43 | { 44 | if (Singleton == null) 45 | { 46 | Singleton = activator(); 47 | Activator = () => Singleton; 48 | } 49 | 50 | return Singleton; 51 | }; 52 | } 53 | 54 | public Binder To() where TInjected : TBinded, new() 55 | { 56 | InjectedType = typeof(TInjected); 57 | CheckInjectedType(); 58 | Activator = BindedActivator.Activator; 59 | return this; 60 | } 61 | } 62 | 63 | public static class BindedActivator where T : new() 64 | { 65 | public static readonly Func Activator; 66 | 67 | static BindedActivator() 68 | { 69 | var constructor = typeof(T).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, 70 | new Type[0], null); 71 | var e = Expression.New(constructor); 72 | Activator = Expression.Lambda>(e).Compile(); 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /TeeSharp.Core/src/Kernel/IKernel.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Core 2 | { 3 | public interface IKernel 4 | { 5 | T Get(); 6 | Binder Bind(); 7 | } 8 | } -------------------------------------------------------------------------------- /TeeSharp.Core/src/Kernel/IKernelConfig.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Core 2 | { 3 | public interface IKernelConfig 4 | { 5 | void Load(IKernel kernel); 6 | } 7 | } -------------------------------------------------------------------------------- /TeeSharp.Core/src/Kernel/Kernel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace TeeSharp.Core 5 | { 6 | public class Kernel : IKernel 7 | { 8 | private readonly Dictionary _binders; 9 | 10 | public Kernel(IKernelConfig config) 11 | { 12 | BaseInterface.Kernel = this; 13 | _binders = new Dictionary(); 14 | config.Load(this); 15 | } 16 | 17 | public T Get() 18 | { 19 | if (_binders.TryGetValue(typeof(T), out var binder)) 20 | return (T) binder.Activator(); 21 | throw new Exception($"Type '{typeof(T).Name}' is not binded"); 22 | } 23 | 24 | public Binder Bind() 25 | { 26 | var binder = new Binder(); 27 | if (_binders.ContainsKey(binder.BindedType)) 28 | _binders[binder.BindedType] = binder; 29 | else 30 | _binders.Add(binder.BindedType, binder); 31 | return binder; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /TeeSharp.Core/src/RNG.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TeeSharp.Core 4 | { 5 | public static class RNG 6 | { 7 | private static readonly Random _random = new Random(); 8 | private static readonly object _sync = new object(); 9 | 10 | public static int Int() 11 | { 12 | lock (_sync) 13 | { 14 | return _random.Next(); 15 | } 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /TeeSharp.Core/src/SanitizeType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TeeSharp.Core 4 | { 5 | [Flags] 6 | public enum SanitizeType 7 | { 8 | Sanitize = 1 << 0, 9 | SanitizeCC = 1 << 1, 10 | SkipStartWhitespaces = 1 << 2 11 | } 12 | } -------------------------------------------------------------------------------- /TeeSharp.Core/src/Secure.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security.Cryptography; 3 | 4 | namespace TeeSharp.Core 5 | { 6 | public static class Secure 7 | { 8 | public static readonly MD5 MD5 9 | = MD5CryptoServiceProvider.Create(); 10 | public static readonly RandomNumberGenerator RNG 11 | = RNGCryptoServiceProvider.Create(); 12 | 13 | static Secure() 14 | { 15 | MD5.Initialize(); 16 | } 17 | 18 | public static void RandomFill(ushort[] array) 19 | { 20 | var buffer = new byte[array.Length * sizeof(ushort)]; 21 | RandomFill(buffer); 22 | Buffer.BlockCopy(buffer, 0, array, 0, buffer.Length); 23 | } 24 | 25 | public static void RandomFill(byte[] bytes) 26 | { 27 | RNG.GetBytes(bytes); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /TeeSharp.Core/src/Time.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | 3 | namespace TeeSharp.Core 4 | { 5 | public static class Time 6 | { 7 | public static long Freq() 8 | { 9 | return Stopwatch.Frequency; 10 | } 11 | 12 | public static long Get() 13 | { 14 | return Stopwatch.GetTimestamp(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /TeeSharp.Demo/TeeSharp.Demo.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | 7.2 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /TeeSharp.Demo/src/Class1.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Demo 2 | { 3 | public class Class1 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /TeeSharp.Map/TeeSharp.Map.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | 7.2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /TeeSharp.Map/src/Datafile/DataFileReader.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Runtime.InteropServices; 3 | using TeeSharp.Core; 4 | using TeeSharp.Core.Extensions; 5 | 6 | namespace TeeSharp.Map 7 | { 8 | /* 9 | data file format: 10 | [ 8] version_header 11 | [ 28] header 12 | [*12] item_types 13 | [* 4] item_offsets 14 | [* 4] data_offsets 15 | [* 4] _data_sizes 16 | [ ] items 17 | [ ] data 18 | */ 19 | 20 | public static class DataFileReader 21 | { 22 | public static DataFile Read(Stream stream, out string error) 23 | { 24 | var buffer = new byte[stream.Length]; 25 | stream.Read(buffer, 0, buffer.Length); 26 | stream.Seek(0, SeekOrigin.Begin); 27 | 28 | var crc = Crc32.ComputeChecksum(buffer); 29 | var header = stream.Read(); 30 | 31 | if (header.IdString != "DATA" && header.IdString != "ATAD") 32 | { 33 | error = $"wrong signature ({header.IdString})"; 34 | return null; 35 | } 36 | 37 | if (header.Version != 4) 38 | { 39 | error = $"wrong version ({header.Version})"; 40 | return null; 41 | } 42 | 43 | var itemTypes = stream.ReadArray(header.NumItemTypes); 44 | var itemOffsets = stream.ReadArray(header.NumItems); 45 | var dataOffsets = stream.ReadArray(header.NumData); 46 | var dataSizes = stream.ReadArray(header.NumData); 47 | var itemStartIndex = stream.Position; 48 | 49 | error = string.Empty; 50 | return new DataFile( 51 | buffer, 52 | crc, 53 | header, 54 | itemTypes, 55 | itemOffsets, 56 | dataOffsets, 57 | dataSizes, 58 | (int) itemStartIndex 59 | ); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /TeeSharp.Map/src/Datafile/DataFileWriter.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Map 2 | { 3 | public class DataFileWriter 4 | { 5 | 6 | 7 | public bool Save(string path) 8 | { 9 | return false; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /TeeSharp.Map/src/Datafile/DataFiles/DataFileItem.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace TeeSharp.Map 4 | { 5 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 6 | public struct DataFileItem 7 | { 8 | /// 9 | /// The type_id__id integer consists of 16 bit type_id of the type the item belongs to and 16 bit id that uniquely identifies the item among all others of the same type, in that order. 10 | /// 11 | [MarshalAs(UnmanagedType.I4)] 12 | public int TypeIdAndItemId; 13 | 14 | /// 15 | /// The size signed 32-bit integer is the size of the item_data field, in bytes, which must be divisible by four. 16 | /// 17 | [MarshalAs(UnmanagedType.I4)] 18 | public int Size; 19 | } 20 | } -------------------------------------------------------------------------------- /TeeSharp.Map/src/Datafile/DataFiles/DataFileItemType.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace TeeSharp.Map 4 | { 5 | /// 6 | /// The item types are an array of item types. The number of item types in that array is num_item_types, each item type is identified by its unique type_id (explained below). 7 | /// 8 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 9 | public struct DataFileItemType 10 | { 11 | /// 12 | /// The type_id 32-bit signed integer must be unique amongst all other item_type.type_ids. Its value must fit into an unsigned 16-bit integer. 13 | /// 14 | [MarshalAs(UnmanagedType.I4)] 15 | public MapItemTypes TypeId; 16 | 17 | /// 18 | /// The start signed integer is the index of the first item in the items with the type type_id. 19 | /// 20 | [MarshalAs(UnmanagedType.I4)] 21 | public int Start; 22 | 23 | /// 24 | /// The num signed integer must be the number of items with the the type type_id. 25 | /// 26 | [MarshalAs(UnmanagedType.I4)] 27 | public int Num; 28 | } 29 | } -------------------------------------------------------------------------------- /TeeSharp.Map/src/Datafile/DataFiles/DataFileVersionHeader.cs: -------------------------------------------------------------------------------- 1 | //using System.Runtime.InteropServices; 2 | 3 | //namespace TeeSharp.Map 4 | //{ 5 | // /// 6 | // /// 8 bytes 7 | // /// The version header consists of a magic byte sequence, identifying the file as a Teeworlds datafile and a version number. 8 | // /// 9 | // [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 10 | // public struct DataFileVersionHeader 11 | // { 12 | // public string Magic => new string(MagicArray); 13 | 14 | // /// 15 | // /// 4 bytes 16 | // /// The magic must exactly be the ASCII representations of the four characters, 17 | // /// 'D', 'A', 'T', 'A'. NOTE: Readers of Teeworlds datafiles should be able to read 18 | // /// datafiles which start with a reversed magic too, that is 'A', 'T', 'A', 'D'. 19 | // /// A bug in the reference implementation caused big-endian machines to save the reversed magic bytes. 20 | // /// 21 | 22 | // //[FieldOffset(0)] 23 | // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] 24 | // public char[] MagicArray; 25 | 26 | // /// 27 | // /// 4 bytes 28 | // /// The version is a little-endian signed 32-bit integer, for version 29 | // /// 3 or 4 of Teeworlds datafiles, it must be 3 or 4, respectively. 30 | // /// 31 | // [MarshalAs(UnmanagedType.I4)] 32 | // public int Version; 33 | // } 34 | //} -------------------------------------------------------------------------------- /TeeSharp.Map/src/LayerType.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Map 2 | { 3 | public enum LayerType 4 | { 5 | Invalid = 0, 6 | Game, 7 | Tiles, 8 | Quads 9 | } 10 | } -------------------------------------------------------------------------------- /TeeSharp.Map/src/MapItemTypes.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Map 2 | { 3 | public enum MapItemTypes 4 | { 5 | Version = 0, 6 | Info, 7 | Image, 8 | Envelope, 9 | Group, 10 | Layer, 11 | EnvelopePoints 12 | } 13 | } -------------------------------------------------------------------------------- /TeeSharp.Map/src/MapItems/Color.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace TeeSharp.Map.MapItems 4 | { 5 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 6 | public struct Color 7 | { 8 | [MarshalAs(UnmanagedType.I4)] public int R; 9 | [MarshalAs(UnmanagedType.I4)] public int G; 10 | [MarshalAs(UnmanagedType.I4)] public int B; 11 | [MarshalAs(UnmanagedType.I4)] public int A; 12 | } 13 | } -------------------------------------------------------------------------------- /TeeSharp.Map/src/MapItems/MapItemGroup.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace TeeSharp.Map.MapItems 4 | { 5 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 6 | public class MapItemGroup 7 | { 8 | public const int CURRENT_VERSION = 3; 9 | 10 | [MarshalAs(UnmanagedType.I4)] 11 | public int Version; 12 | 13 | [MarshalAs(UnmanagedType.I4)] 14 | public int OffsetX; 15 | 16 | [MarshalAs(UnmanagedType.I4)] 17 | public int OffsetY; 18 | 19 | [MarshalAs(UnmanagedType.I4)] 20 | public int ParallaxX; 21 | 22 | [MarshalAs(UnmanagedType.I4)] 23 | public int ParallaxY; 24 | 25 | [MarshalAs(UnmanagedType.I4)] 26 | public int StartLayer; 27 | 28 | [MarshalAs(UnmanagedType.I4)] 29 | public int NumLayers; 30 | 31 | [MarshalAs(UnmanagedType.I4)] 32 | public int UseClipping; 33 | 34 | [MarshalAs(UnmanagedType.I4)] 35 | public int ClipX; 36 | 37 | [MarshalAs(UnmanagedType.I4)] 38 | public int ClipY; 39 | 40 | [MarshalAs(UnmanagedType.I4)] 41 | public int ClipW; 42 | 43 | [MarshalAs(UnmanagedType.I4)] 44 | public int ClipH; 45 | 46 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] 47 | public int[] IntName; 48 | } 49 | } -------------------------------------------------------------------------------- /TeeSharp.Map/src/MapItems/MapItemImage.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace TeeSharp.Map.MapItems 4 | { 5 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 6 | public class MapItemImage 7 | { 8 | [MarshalAs(UnmanagedType.I4)] 9 | public int Version; 10 | 11 | [MarshalAs(UnmanagedType.I4)] 12 | public int Width; 13 | 14 | [MarshalAs(UnmanagedType.I4)] 15 | public int Height; 16 | 17 | [MarshalAs(UnmanagedType.I4)] 18 | public int External; 19 | 20 | [MarshalAs(UnmanagedType.I4)] 21 | public int ImageName; 22 | 23 | [MarshalAs(UnmanagedType.I4)] 24 | public int ImageData; 25 | 26 | [MarshalAs(UnmanagedType.I4)] 27 | public int Format; 28 | } 29 | } -------------------------------------------------------------------------------- /TeeSharp.Map/src/MapItems/MapItemInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace TeeSharp.Map.MapItems 4 | { 5 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 6 | public class MapItemInfo 7 | { 8 | [MarshalAs(UnmanagedType.I4)] 9 | public int Version; 10 | 11 | [MarshalAs(UnmanagedType.I4)] 12 | public int Author; 13 | 14 | [MarshalAs(UnmanagedType.I4)] 15 | public int MapVersion; 16 | 17 | [MarshalAs(UnmanagedType.I4)] 18 | public int Credits; 19 | 20 | [MarshalAs(UnmanagedType.I4)] 21 | public int License; 22 | } 23 | } -------------------------------------------------------------------------------- /TeeSharp.Map/src/MapItems/MapItemLayer.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace TeeSharp.Map.MapItems 4 | { 5 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 6 | public class MapItemLayer 7 | { 8 | [MarshalAs(UnmanagedType.I4)] 9 | public int Version; 10 | 11 | [MarshalAs(UnmanagedType.I4)] 12 | public LayerType Type; 13 | 14 | [MarshalAs(UnmanagedType.I4)] 15 | public int Flags; 16 | } 17 | } -------------------------------------------------------------------------------- /TeeSharp.Map/src/MapItems/MapItemLayerQuads.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace TeeSharp.Map.MapItems 4 | { 5 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 6 | public class MapItemLayerQuads 7 | { 8 | public MapItemLayer Layer; 9 | 10 | [MarshalAs(UnmanagedType.I4)] 11 | public int Version; 12 | 13 | [MarshalAs(UnmanagedType.I4)] 14 | public int NumQuads; 15 | 16 | [MarshalAs(UnmanagedType.I4)] 17 | public int Data; 18 | 19 | [MarshalAs(UnmanagedType.I4)] 20 | public int Image; 21 | 22 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] 23 | public int[] IntName; 24 | } 25 | } -------------------------------------------------------------------------------- /TeeSharp.Map/src/MapItems/MapItemLayerTilemap.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace TeeSharp.Map.MapItems 4 | { 5 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 6 | public class MapItemLayerTilemap 7 | { 8 | public MapItemLayer Layer; 9 | 10 | [MarshalAs(UnmanagedType.I4)] 11 | public int Version; 12 | 13 | [MarshalAs(UnmanagedType.I4)] 14 | public int Width; 15 | 16 | [MarshalAs(UnmanagedType.I4)] 17 | public int Height; 18 | 19 | [MarshalAs(UnmanagedType.I4)] 20 | public int Flags; 21 | 22 | public Color Color; 23 | 24 | [MarshalAs(UnmanagedType.I4)] 25 | public int ColorEnv; 26 | 27 | [MarshalAs(UnmanagedType.I4)] 28 | public int ColorEnvOffset; 29 | 30 | [MarshalAs(UnmanagedType.I4)] 31 | public int Image; 32 | 33 | [MarshalAs(UnmanagedType.I4)] 34 | public int Data; 35 | 36 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] 37 | public int[] IntName; 38 | } 39 | } -------------------------------------------------------------------------------- /TeeSharp.Map/src/MapItems/MapItemVersion.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace TeeSharp.Map.MapItems 4 | { 5 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 6 | public class MapItemVersion 7 | { 8 | [MarshalAs(UnmanagedType.I4)] 9 | public int Version; 10 | } 11 | } -------------------------------------------------------------------------------- /TeeSharp.Map/src/MapItems/Point.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace TeeSharp.Map.MapItems 4 | { 5 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 6 | public struct Point 7 | { 8 | [MarshalAs(UnmanagedType.I4)] 9 | public int X; // 22.10 fixed point 10 | 11 | [MarshalAs(UnmanagedType.I4)] 12 | public int Y; // 22.10 fixed point 13 | } 14 | } -------------------------------------------------------------------------------- /TeeSharp.Map/src/MapItems/Quad.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace TeeSharp.Map.MapItems 4 | { 5 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 6 | public struct Quad 7 | { 8 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] 9 | public Point[] Points; 10 | 11 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] 12 | public Color[] Colors; 13 | 14 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] 15 | public Point[] TexCoords; 16 | 17 | [MarshalAs(UnmanagedType.I4)] 18 | public int PosEnv; 19 | 20 | [MarshalAs(UnmanagedType.I4)] 21 | public int PosEnvOffset; 22 | 23 | [MarshalAs(UnmanagedType.I4)] 24 | public int ColorEnv; 25 | 26 | [MarshalAs(UnmanagedType.I4)] 27 | public int ColorEnvOffset; 28 | } 29 | } -------------------------------------------------------------------------------- /TeeSharp.Map/src/MapItems/Tile.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace TeeSharp.Map.MapItems 4 | { 5 | [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 6 | public struct Tile 7 | { 8 | [MarshalAs(UnmanagedType.U1)] 9 | public byte Index; 10 | 11 | [MarshalAs(UnmanagedType.U1)] 12 | public byte Flags; 13 | 14 | [MarshalAs(UnmanagedType.U1)] 15 | public byte Skip; 16 | 17 | [MarshalAs(UnmanagedType.U1)] 18 | public byte Reserved; 19 | } 20 | } -------------------------------------------------------------------------------- /TeeSharp.MasterServer/TeeSharp.MasterServer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | 7.2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TeeSharp.MasterServer/src/MasterServerAddr.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace TeeSharp.MasterServer 4 | { 5 | [StructLayout(LayoutKind.Sequential, Pack = 1)] 6 | public struct MasterServerAddr 7 | { 8 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] 9 | public byte[] Ip; 10 | 11 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] 12 | public byte[] Port; 13 | } 14 | } -------------------------------------------------------------------------------- /TeeSharp.MasterServer/src/MasterServerHelper.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.MasterServer 2 | { 3 | public class MasterServerHelper 4 | { 5 | /// 6 | /// Master server port 7 | /// 8 | public const int Port = 8283; 9 | } 10 | } -------------------------------------------------------------------------------- /TeeSharp.MasterServer/src/MasterServerPackets.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.MasterServer 2 | { 3 | public static class MasterServerPackets 4 | { 5 | public static readonly byte[] Heartbeat = Packet('b', 'e', 'a', '2'); 6 | 7 | public static readonly byte[] GetList = Packet('r', 'e', 'q', '2'); 8 | public static readonly byte[] List = Packet('l', 'i', 's', '2'); 9 | 10 | public static readonly byte[] GetCount = Packet('c', 'o', 'u', '2'); 11 | public static readonly byte[] Count = Packet('s', 'i', 'z', '2'); 12 | 13 | public static readonly byte[] GetInfo = Packet('g', 'i', 'e', '3'); 14 | public static readonly byte[] Info = Packet('i', 'n', 'f', '3'); 15 | 16 | public static readonly byte[] FwCheck = Packet('f', 'w', '?', '?'); 17 | public static readonly byte[] FwResponse = Packet('f', 'w', '!', '!'); 18 | public static readonly byte[] FwOk = Packet('f', 'w', 'o', 'k'); 19 | public static readonly byte[] FwError = Packet('f', 'w', 'e', 'r'); 20 | 21 | private static byte[] Packet(char b1, char b2, char b3, char b4) 22 | { 23 | return new byte[] {255, 255, 255, 255, (byte) b1, (byte) b2, (byte) b3, (byte) b4}; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /TeeSharp.MasterServer/src/ServerInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | 3 | namespace TeeSharp.MasterServer 4 | { 5 | public class ServerInfo 6 | { 7 | public class PlayerInfo 8 | { 9 | public string Name { get; set; } 10 | public string Clan { get; set; } 11 | public CountryInfo Country { get; set; } 12 | public int Score { get; set; } 13 | public bool InGame { get; set; } 14 | } 15 | 16 | public PlayerInfo[] Players { get; set; } 17 | public IPEndPoint Ip { get; set; } 18 | public string Version { get; set; } 19 | public string Name { get; set; } 20 | public string Map { get; set; } 21 | public string GameType { get; set; } 22 | public int NumPlayers { get; set; } 23 | public int MaxPlayers { get; set; } 24 | public int NumClients { get; set; } 25 | public int MaxClients { get; set; } 26 | } 27 | } -------------------------------------------------------------------------------- /TeeSharp.MasterServer/src/ServersSnapshot.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net; 4 | 5 | namespace TeeSharp.MasterServer 6 | { 7 | public class ServersSnapshotItem 8 | { 9 | public DateTime? LastUpdateInfo { get; set; } 10 | public ServerInfo ServerInfo { get; set; } 11 | } 12 | 13 | public class ServersSnapshot 14 | { 15 | public int ServersCount { get; private set; } 16 | public int ServersOnline { get; private set; } 17 | 18 | private readonly Dictionary _servers; 19 | 20 | public ServersSnapshot() 21 | { 22 | _servers = new Dictionary(); 23 | } 24 | 25 | public void UpdateServerInfo(IPEndPoint serverAddr, ServerInfo info) 26 | { 27 | if (!_servers.ContainsKey(serverAddr)) 28 | return; 29 | 30 | ServersOnline++; 31 | 32 | _servers[serverAddr].LastUpdateInfo = DateTime.Now; 33 | _servers[serverAddr].ServerInfo = info; 34 | } 35 | 36 | public void AddServer(IPEndPoint serverAddr) 37 | { 38 | if (_servers.ContainsKey(serverAddr)) 39 | return; 40 | 41 | ServersCount++; 42 | 43 | _servers.Add(serverAddr, new ServersSnapshotItem 44 | { 45 | LastUpdateInfo = null, 46 | }); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /TeeSharp.Network/TeeSharp.Network.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | 7.2 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /TeeSharp.Network/src/Abstract/BaseChunkReceiver.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using TeeSharp.Core; 3 | 4 | namespace TeeSharp.Network 5 | { 6 | public abstract class BaseChunkReceiver : BaseInterface 7 | { 8 | public virtual ChunkConstruct ChunkConstruct { get; protected set; } 9 | 10 | protected virtual bool Valid { get; set; } 11 | protected virtual int CurrentChunk { get; set; } 12 | protected virtual int ClientId { get; set; } 13 | protected virtual BaseNetworkConnection Connection { get; set; } 14 | protected virtual IPEndPoint EndPoint { get; set; } 15 | 16 | public abstract void Clear(); 17 | public abstract void Start(IPEndPoint remote, 18 | BaseNetworkConnection connection, int clientId); 19 | public abstract bool FetchChunk(ref Chunk packet); 20 | } 21 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/Abstract/BaseNetworkBan.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using TeeSharp.Core; 3 | 4 | namespace TeeSharp.Network 5 | { 6 | public abstract class BaseNetworkBan : BaseInterface 7 | { 8 | public abstract void Update(); 9 | public abstract bool BanAddr(IPEndPoint clientAddr, int seconds, string reason); 10 | public abstract bool IsBanned(IPEndPoint remote, out string reason); 11 | } 12 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/Abstract/BaseNetworkClient.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using System.Net.Sockets; 3 | using TeeSharp.Core; 4 | using TeeSharp.Network.Enums; 5 | 6 | namespace TeeSharp.Network 7 | { 8 | public struct NetworkClientConfig 9 | { 10 | public IPEndPoint LocalEndPoint; 11 | public ConnectionConfig ConnectionConfig; 12 | } 13 | 14 | public abstract class BaseNetworkClient : BaseInterface 15 | { 16 | public virtual ClientState State 17 | { 18 | get 19 | { 20 | if (Connection.State == ConnectionState.Online) 21 | return ClientState.Online; 22 | if (Connection.State == ConnectionState.Offline) 23 | return ClientState.Offline; 24 | return ClientState.Connecting; 25 | } 26 | } 27 | 28 | protected virtual BaseNetworkConnection Connection { get; set; } 29 | protected virtual BaseChunkReceiver ChunkReceiver { get; set; } 30 | protected virtual UdpClient UdpClient { get; set; } 31 | 32 | protected virtual BaseTokenCache TokenCache { get; set; } 33 | protected virtual BaseTokenManager TokenManager { get; set; } 34 | protected virtual NetworkClientConfig Config { get; set; } 35 | 36 | public abstract void Init(); 37 | public abstract bool Open(NetworkClientConfig config); 38 | public abstract void Close(); 39 | 40 | public abstract void Disconnect(string reason); 41 | public abstract bool Connect(IPEndPoint endPoint); 42 | public abstract void Update(); 43 | 44 | public abstract bool Receive(ref Chunk packet, ref uint token); 45 | public abstract void Send(Chunk packet, 46 | uint token = TokenHelper.TokenNone, 47 | SendCallbackData callbackData = null); 48 | public abstract void PurgeStoredPacket(int trackId); 49 | 50 | public abstract void Flush(); 51 | public abstract bool GotProblems(); 52 | } 53 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/Abstract/BaseNetworkServer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Net; 3 | using System.Net.Sockets; 4 | using TeeSharp.Core; 5 | 6 | namespace TeeSharp.Network 7 | { 8 | public delegate void ClientConnectedEvent(int clientId); 9 | public delegate void ClientDisconnectedEvent(int clientId, string reason); 10 | 11 | public struct NetworkServerConfig 12 | { 13 | public IPEndPoint BindEndPoint; 14 | public int MaxClients; 15 | public int MaxClientsPerIp; 16 | public ConnectionConfig ConnectionConfig; 17 | } 18 | 19 | public abstract class BaseNetworkServer : BaseInterface 20 | { 21 | public virtual event ClientConnectedEvent ClientConnected; 22 | public virtual event ClientDisconnectedEvent ClientDisconnected; 23 | 24 | public virtual NetworkServerConfig Config { get; protected set; } 25 | 26 | protected virtual UdpClient UdpClient { get; set; } 27 | protected virtual BaseNetworkBan NetworkBan { get; set; } 28 | protected virtual IList Connections { get; set; } 29 | 30 | protected virtual BaseChunkReceiver ChunkReceiver { get; set; } 31 | 32 | protected virtual BaseTokenManager TokenManager { get; set; } 33 | protected virtual BaseTokenCache TokenCache { get; set; } 34 | 35 | public abstract void Init(); 36 | public abstract bool Open(NetworkServerConfig config); 37 | 38 | public abstract void SetMaxClientsPerIp(int max); 39 | 40 | public abstract IPEndPoint ClientEndPoint(int clientId); 41 | public abstract void Update(); 42 | public abstract bool Receive(ref Chunk packet, ref uint token); 43 | public abstract void Drop(int clientId, string reason); 44 | public abstract bool Send(Chunk packet, uint token = 4294967295U); 45 | public abstract void AddToken(IPEndPoint endPoint, uint token); 46 | 47 | protected abstract NetworkServerConfig CheckConfig( 48 | NetworkServerConfig config); 49 | 50 | protected void OnClientConnected(int clientId) 51 | { 52 | ClientConnected?.Invoke(clientId); 53 | } 54 | 55 | protected void OnClientDisconnected(int clientId, string reason) 56 | { 57 | ClientDisconnected?.Invoke(clientId, reason); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /TeeSharp.Network/src/Abstract/BaseTokenCache.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Net; 3 | using System.Net.Sockets; 4 | using TeeSharp.Core; 5 | using TeeSharp.Network.Enums; 6 | 7 | namespace TeeSharp.Network 8 | { 9 | public abstract class BaseTokenCache : BaseInterface 10 | { 11 | protected struct AddressInfo 12 | { 13 | public IPEndPoint EndPoint; 14 | public uint Token; 15 | public long Expiry; 16 | } 17 | 18 | protected class ConnlessPacketInfo 19 | { 20 | public int TrackID { get; } 21 | public int DataSize { get; } 22 | public byte[] Data { get; } 23 | 24 | public IPEndPoint EndPoint { get; set; } 25 | public long Expiry { get; set; } 26 | public long LastTokenRequest { get; set; } 27 | public SendCallback SendCallback { get; set; } 28 | public object CallbackContext { get; set; } 29 | 30 | 31 | private static int _uniqueID = 0; 32 | 33 | public ConnlessPacketInfo(int dataSize) 34 | { 35 | DataSize = dataSize; 36 | Data = new byte[dataSize]; 37 | TrackID = _uniqueID++; 38 | } 39 | } 40 | 41 | protected virtual BaseTokenManager TokenManager { get; set; } 42 | protected virtual UdpClient Client { get; set; } 43 | protected virtual IList ConnlessPacketList { get; set; } 44 | protected virtual IList TokenCache { get; set; } 45 | 46 | public abstract void Init(UdpClient client, BaseTokenManager tokenManager); 47 | public abstract void SendPacketConnless(IPEndPoint endPoint, 48 | byte[] data, int dataSize, SendCallbackData callbackData = null); 49 | public abstract void PurgeStoredPacket(int trackId); 50 | public abstract void FetchToken(IPEndPoint endPoint); 51 | public abstract void AddToken(IPEndPoint endPoint, 52 | uint token, TokenFlags tokenFlags); 53 | public abstract uint GetToken(IPEndPoint endPoint); 54 | public abstract void Update(); 55 | } 56 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/Abstract/BaseTokenManager.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using System.Net.Sockets; 3 | using TeeSharp.Core; 4 | 5 | namespace TeeSharp.Network 6 | { 7 | public abstract class BaseTokenManager : BaseInterface 8 | { 9 | protected virtual UdpClient Client { get; set; } 10 | 11 | protected virtual uint GlobalToken { get; set; } 12 | protected virtual uint PreviousGlobalToken { get; set; } 13 | 14 | protected virtual long Seed { get; set; } 15 | protected virtual long NextSeedTime { get; set; } 16 | protected virtual long PreviousSeed { get; set; } 17 | protected virtual int SeedTime { get; set; } 18 | 19 | public abstract void Init(UdpClient client, int seedTime = NetworkHelper.SeedTime); 20 | public abstract void Update(); 21 | public abstract void GenerateSeed(); 22 | public abstract int ProcessMessage(IPEndPoint endPoint, 23 | ChunkConstruct chunkConstruct); 24 | public abstract bool CheckToken(IPEndPoint endPoint, uint token, 25 | uint responseToken, ref bool broadcastResponse); 26 | public abstract uint GenerateToken(IPEndPoint endPoint); 27 | public abstract uint GenerateToken(IPEndPoint endPoint, long seed); 28 | } 29 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/Chunk.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using TeeSharp.Network.Enums; 3 | 4 | namespace TeeSharp.Network 5 | { 6 | public class Chunk 7 | { 8 | public int ClientId { get; set; } 9 | public SendFlags Flags { get; set; } 10 | public IPEndPoint EndPoint { get; set; } 11 | public int DataSize { get; set; } 12 | public byte[] Data { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/ChunkConstruct.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Network.Enums; 2 | using Token = System.UInt32; 3 | 4 | namespace TeeSharp.Network 5 | { 6 | public class ChunkConstruct 7 | { 8 | public Token Token { get; set; } 9 | public Token ResponseToken { get; set; } 10 | 11 | public PacketFlags Flags { get; set; } 12 | public int Ack { get; set; } 13 | public int NumChunks { get; set; } 14 | public int DataSize { get; set; } 15 | public byte[] Data { get; } 16 | 17 | public ChunkConstruct(int bufferSize) 18 | { 19 | Data = new byte[bufferSize]; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/ChunkHeader.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Network.Enums; 2 | 3 | namespace TeeSharp.Network 4 | { 5 | public class ChunkHeader 6 | { 7 | public ChunkFlags Flags { get; set; } 8 | public int Size { get; set; } 9 | public int Sequence { get; set; } 10 | 11 | public int Pack(byte[] inputData, int inputOffset) 12 | { 13 | inputData[inputOffset + 0] = 14 | (byte) ((((int) Flags & 0x03) << 6) | ((Size >> 6) & 0x3F)); 15 | inputData[inputOffset + 1] = (byte) (Size & 0x3F); 16 | 17 | if (Flags.HasFlag(ChunkFlags.Vital)) 18 | { 19 | inputData[inputOffset + 1] |= (byte) ((Sequence >> 2) & 0xC0); 20 | inputData[inputOffset + 2] = (byte) (Sequence & 0xFF); 21 | return inputOffset + 3; 22 | } 23 | 24 | return inputOffset + 2; 25 | } 26 | 27 | public int Unpack(byte[] inputData, int inputOffset) 28 | { 29 | Sequence = -1; 30 | Flags = (ChunkFlags) ((inputData[inputOffset + 0] >> 6) & 0x03); 31 | Size = ((inputData[inputOffset + 0] & 0x3F) << 6) | 32 | ((inputData[inputOffset + 1] & 0x3F)); 33 | 34 | if (Flags.HasFlag(ChunkFlags.Vital)) 35 | { 36 | Sequence = ((inputData[inputOffset + 1] & 0xC0) << 2) | 37 | ((inputData[inputOffset + 2])); 38 | return inputOffset + 3; 39 | } 40 | 41 | return inputOffset + 2; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/ChunkResend.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Network.Enums; 2 | 3 | namespace TeeSharp.Network 4 | { 5 | public class ChunkResend 6 | { 7 | public int Sequence { get; set; } 8 | public ChunkFlags Flags { get; set; } 9 | public int DataSize { get; set; } 10 | public byte[] Data { get; set; } 11 | public long FirstSendTime { get; set; } 12 | public long LastSendTime { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/Enums/ChunkFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TeeSharp.Network.Enums 4 | { 5 | [Flags] 6 | public enum ChunkFlags 7 | { 8 | None = 0, 9 | Vital = 1, 10 | Resend = 2 11 | } 12 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/Enums/ClientState.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Network.Enums 2 | { 3 | public enum ClientState 4 | { 5 | Offline = 0, 6 | Connecting, 7 | Online 8 | } 9 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/Enums/ConnectionMessages.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Network.Enums 2 | { 3 | public enum ConnectionMessages 4 | { 5 | KeepAlive = 0, 6 | Connect, 7 | ConnectAccept, 8 | Accept, 9 | Close, 10 | Token 11 | } 12 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/Enums/ConnectionState.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Network.Enums 2 | { 3 | public enum ConnectionState 4 | { 5 | Offline = 0, 6 | Token, 7 | Connect, 8 | Pending, 9 | Online, 10 | Error 11 | } 12 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/Enums/PacketFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TeeSharp.Network.Enums 4 | { 5 | [Flags] 6 | public enum PacketFlags 7 | { 8 | None = 0, 9 | Control = 1, 10 | Resend = 2, 11 | Compression = 4, 12 | Connless = 8 13 | } 14 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/Enums/SendFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TeeSharp.Network.Enums 4 | { 5 | [Flags] 6 | public enum SendFlags 7 | { 8 | None = 0, 9 | Vital = 1, 10 | Connless = 2, 11 | Flush = 4, 12 | } 13 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/Enums/TokenFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TeeSharp.Network.Enums 4 | { 5 | [Flags] 6 | public enum TokenFlags 7 | { 8 | None = 0, 9 | AllowBroadcast = 1, 10 | ResponseOnly = 2, 11 | } 12 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/Extensions/NetworkExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Net.Sockets; 4 | 5 | namespace TeeSharp.Network.Extensions 6 | { 7 | public static class NetworkExtensions 8 | { 9 | private const int 10 | TypeInvalid = 0, 11 | TypeIPv4 = 1, 12 | TypeIPv6 = 2, 13 | LinkBroadcast = 4, 14 | TypeAll = TypeIPv4 | TypeIPv6; 15 | 16 | public static bool Compare(this IPEndPoint self, IPEndPoint other, 17 | bool comparePorts) 18 | { 19 | return self.Address.Equals(other.Address) && (!comparePorts || self.Port == other.Port); 20 | } 21 | 22 | /// 23 | /// Serialize IPEndPoint to 24 byte array [4 bytes endpoint type, 16 bytes ip address, 4 bytes port] 24 | /// 25 | /// Serialized endpoint 26 | /// 27 | public static byte[] Raw(this IPEndPoint endPoint) 28 | { 29 | var array = new byte[sizeof(uint) + sizeof(byte) * 16 + sizeof(ushort) + 2]; // 0 type, 4 ip, 20 port, padding 2 bytes 30 | var bytes = new Span(array); 31 | var type = TypeInvalid; 32 | 33 | switch (endPoint.AddressFamily) 34 | { 35 | case AddressFamily.InterNetwork: 36 | type = TypeIPv4; 37 | break; 38 | case AddressFamily.InterNetworkV6: 39 | type = TypeIPv6; 40 | break; 41 | } 42 | 43 | BitConverter.TryWriteBytes(bytes, (uint) type); // type 44 | endPoint.Address.GetAddressBytes().AsSpan().CopyTo(bytes.Slice(4)); // address bytes 45 | BitConverter.TryWriteBytes(bytes.Slice(20), (ushort) endPoint.Port); // port 46 | return array; 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/NetworkBan.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | 3 | namespace TeeSharp.Network 4 | { 5 | public class NetworkBan : BaseNetworkBan 6 | { 7 | public override void Update() 8 | { 9 | } 10 | 11 | public override bool BanAddr(IPEndPoint clientAddr, int seconds, string reason) 12 | { 13 | return true; 14 | } 15 | 16 | public override bool IsBanned(IPEndPoint remote, out string reason) 17 | { 18 | reason = null; 19 | return false; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/SendCallbackData.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Network 2 | { 3 | public delegate void SendCallback(int trackID, object context); 4 | 5 | public class SendCallbackData 6 | { 7 | public SendCallback Callback { get; set; } 8 | public object Context { get; set; } 9 | public int TrackID { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /TeeSharp.Network/src/TokenHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using TeeSharp.Network.Extensions; 4 | 5 | namespace TeeSharp.Network 6 | { 7 | public static class TokenHelper 8 | { 9 | public const int 10 | TokenCacheSize = 64, 11 | TokenCacheAddressExpiry = NetworkHelper.SeedTime, 12 | TokenCachePacketExpiry = 5, 13 | TokenRequestDataSize = 512; 14 | 15 | public const uint 16 | TokenMax = 0xffffffff, 17 | TokenNone = TokenMax, 18 | TokenMask = TokenMax; 19 | 20 | public static uint GenerateToken(IPEndPoint address, long seed) 21 | { 22 | var buffer = new byte[24 + sizeof(long)]; // sizeof(address raw) + sizeof(long) 23 | var bytes = new Span(buffer); 24 | 25 | // TODO 26 | //if (pAddr->type & NETTYPE_LINK_BROADCAST) 27 | // return GenerateToken(&NullAddr, Seed); 28 | 29 | if (address != null) 30 | { 31 | var port = address.Port; 32 | address.Port = 0; 33 | address.Raw().CopyTo(bytes); 34 | address.Port = port; 35 | } 36 | 37 | BitConverter.TryWriteBytes(bytes.Slice(24), seed); 38 | 39 | var result = NetworkHelper.Hash(buffer) & TokenMask; 40 | if (result == TokenNone) 41 | result--; 42 | 43 | return result; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /TeeSharp.Server/TeeSharp.Server.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | 7.2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /TeeSharp.Server/src/Game/Abstract/BaseEvents.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using TeeSharp.Common; 3 | using TeeSharp.Common.Snapshots; 4 | using TeeSharp.Core; 5 | 6 | namespace TeeSharp.Server.Game 7 | { 8 | public abstract class BaseEvents : BaseInterface 9 | { 10 | public struct EventInfo 11 | { 12 | public BaseSnapshotEvent EventItem; 13 | public int Mask; 14 | } 15 | 16 | protected abstract IList EventInfos { get; set; } 17 | protected virtual int MaxEvents { get; set; } 18 | protected virtual BaseGameContext GameContext { get; set; } 19 | protected virtual BaseServer Server { get; set; } 20 | 21 | public abstract T Create(Vector2 position, int mask = -1) where T : BaseSnapshotEvent, new(); 22 | public abstract void Init(); 23 | public abstract void Clear(); 24 | public abstract void OnSnapshot(int snappingClient); 25 | } 26 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Game/Abstract/BaseGameWorld.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TeeSharp.Common; 3 | using TeeSharp.Common.Config; 4 | using TeeSharp.Common.Game; 5 | using TeeSharp.Core; 6 | using TeeSharp.Server.Game.Entities; 7 | 8 | namespace TeeSharp.Server.Game 9 | { 10 | public abstract class BaseGameWorld : BaseInterface 11 | { 12 | public abstract event Action Reseted; 13 | 14 | public virtual bool Paused { get; set; } 15 | public virtual WorldCore WorldCore { get; set; } 16 | public virtual bool ResetRequested { get; set; } 17 | 18 | protected virtual BaseGameContext GameContext { get; set; } 19 | protected virtual BaseServer Server { get; set; } 20 | protected virtual BaseConfig Config { get; set; } 21 | 22 | public abstract BaseCharacter IntersectCharacter(Vector2 pos1, Vector2 pos2, 23 | float radius, ref Vector2 newPos, BaseCharacter notThis); 24 | 25 | protected abstract void Reset(); 26 | 27 | public abstract void Tick(); 28 | public abstract void BeforeSnapshot(); 29 | public abstract void OnSnapshot(int snappingClient); 30 | public abstract void AfterSnapshot(); 31 | } 32 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Game/Abstract/BaseVotes.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using TeeSharp.Common.Config; 3 | using TeeSharp.Common.Console; 4 | using TeeSharp.Common.Enums; 5 | using TeeSharp.Common.Protocol; 6 | using TeeSharp.Core; 7 | 8 | namespace TeeSharp.Server.Game 9 | { 10 | public class VoteOption 11 | { 12 | public const int MaxDescription = 64; 13 | public const int MaxCommand = 512; 14 | 15 | public string Description { get; set; } 16 | public string Command { get; set; } 17 | } 18 | 19 | public class ActiveVote 20 | { 21 | public int CallerId { get; set; } 22 | public string Description { get; set; } 23 | public string Reason { get; set; } 24 | public string Command { get; set; } 25 | public Vote Type { get; set; } 26 | public int CloseTick { get; set; } 27 | public int? ClientId { get; set; } 28 | 29 | public int VotesTotal { get; set; } 30 | public int VotesYes { get; set; } 31 | public int VotesNo { get; set; } 32 | } 33 | 34 | 35 | public abstract class BaseVotes : BaseInterface 36 | { 37 | protected struct PlayerVoteInfo 38 | { 39 | public int LastVoteTry { get; set; } 40 | public int LastVoteCall { get; set; } 41 | public int Vote { get; set; } 42 | } 43 | 44 | protected virtual ActiveVote ActiveVote { get; set; } 45 | protected virtual PlayerVoteInfo[] PlayersVoteInfo { get; set; } 46 | 47 | protected virtual BaseGameContext GameContext { get; set; } 48 | protected virtual BaseServer Server { get; set; } 49 | protected virtual BaseConfig Config { get; set; } 50 | protected virtual BaseGameConsole Console { get; set; } 51 | 52 | protected virtual IDictionary VoteOptions { get; set; } 53 | 54 | public abstract void Init(); 55 | public abstract void Tick(); 56 | 57 | public abstract bool AddVote(string description, string command); 58 | public abstract bool ContainsVote(string description); 59 | 60 | public abstract void ClientVote(GameMsg_ClVote message, BasePlayer player); 61 | public abstract void CallVote(GameMsg_ClCallVote message, BasePlayer player); 62 | public abstract void SendVotes(BasePlayer player); 63 | public abstract void SendVoteSet(Vote type, BasePlayer player); 64 | public abstract void SendVoteStatus(BasePlayer player); 65 | public abstract void ClearOptions(BasePlayer player); 66 | 67 | public abstract void StartVote(ActiveVote vote); 68 | public abstract void EndVote(Vote type); 69 | 70 | protected abstract void OnPlayerEnter(BasePlayer player); 71 | protected abstract void OnPlayerLeave(BasePlayer player, string reason); 72 | protected abstract void CheckVoteStatus(); 73 | } 74 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Game/Entities/Flag.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Enums; 2 | 3 | namespace TeeSharp.Server.Game.Entities 4 | { 5 | public class Flag : Entity 6 | { 7 | public override float ProximityRadius { get; protected set; } 8 | 9 | public BaseCharacter Carrier { get; protected set; } 10 | public Team Team { get; protected set; } 11 | 12 | public Flag() : base(idsCount: 1) 13 | { 14 | } 15 | 16 | public override void OnSnapshot(int snappingClient) 17 | { 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Game/Events.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using TeeSharp.Common; 3 | 4 | namespace TeeSharp.Server.Game 5 | { 6 | public class Events : BaseEvents 7 | { 8 | protected override IList EventInfos { get; set; } 9 | 10 | public override T Create(Vector2 position, int mask = -1) 11 | { 12 | if (EventInfos.Count == MaxEvents) 13 | return null; 14 | 15 | var info = new EventInfo 16 | { 17 | EventItem = new T() 18 | { 19 | X = (int) position.x, 20 | Y = (int) position.y 21 | }, 22 | Mask = mask 23 | }; 24 | EventInfos.Add(info); 25 | 26 | return (T) info.EventItem; 27 | } 28 | 29 | public override void Init() 30 | { 31 | GameContext = Kernel.Get(); 32 | Server = Kernel.Get(); 33 | 34 | MaxEvents = 128; 35 | EventInfos = new List(128); 36 | } 37 | 38 | public override void Clear() 39 | { 40 | EventInfos.Clear(); 41 | } 42 | 43 | public override void OnSnapshot(int snappingClient) 44 | { 45 | for (var i = 0; i < EventInfos.Count; i++) 46 | { 47 | if (snappingClient == -1 || BaseGameContext.MaskIsSet(EventInfos[i].Mask, snappingClient)) 48 | { 49 | if (snappingClient == -1 || 50 | MathHelper.Distance(GameContext.Players[snappingClient].ViewPos, 51 | new Vector2(EventInfos[i].EventItem.X, EventInfos[i].EventItem.Y)) < 1500f) 52 | { 53 | Server.SnapshotItem(EventInfos[i].EventItem, i); 54 | } 55 | } 56 | } 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Game/Extensions.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Server.Game 2 | { 3 | public static class Extensions 4 | { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Game/Extensions/EntityExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using TeeSharp.Common; 3 | 4 | namespace TeeSharp.Server.Game 5 | { 6 | public static class EntityExtensions 7 | { 8 | public static IEnumerable Find(this IEnumerable entities, Vector2 position, float radius) where T : Entity 9 | { 10 | foreach (var entity in entities) 11 | { 12 | if (MathHelper.Distance(entity.Position, position) < radius + entity.ProximityRadius) 13 | yield return entity; 14 | } 15 | } 16 | 17 | public static T Closest(this IEnumerable entities, Vector2 pos, float radius, T notThis) where T : Entity 18 | { 19 | var closestRange = radius * 2f; 20 | T closest = null; 21 | 22 | foreach (var entity in entities) 23 | { 24 | if (entity == notThis) 25 | continue; 26 | 27 | var len = MathHelper.Distance(pos, entity.Position); 28 | if (len < entity.ProximityRadius + radius) 29 | { 30 | if (len < closestRange) 31 | { 32 | closestRange = len; 33 | closest = entity; 34 | } 35 | } 36 | } 37 | 38 | return closest; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Game/GameState.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Server.Game 2 | { 3 | public enum GameState 4 | { 5 | /// 6 | /// Warmup started by game because there're not enough players (infinite) 7 | /// 8 | WarmupGame = 0, 9 | 10 | /// 11 | /// Warmup started by user action via rcon or new match (infinite or timer) 12 | /// 13 | WarmupUser, 14 | 15 | /// 16 | /// Start countown to unpause the game or start match/round (tick timer) 17 | /// 18 | StartCountdown, 19 | 20 | /// 21 | /// Game paused (infinite or tick timer) 22 | /// 23 | GamePaused, 24 | 25 | /// 26 | /// Game running (infinite) 27 | /// 28 | GameRunning, 29 | 30 | /// 31 | /// Match is over (tick timer) 32 | /// 33 | EndMatch, 34 | 35 | /// 36 | /// Round is over (tick timer) 37 | /// 38 | EndRound, 39 | } 40 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Game/Gamemodes/GameControllerCTF.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Server.Game 2 | { 3 | public class GameControllerCTF : GameController 4 | { 5 | public override string GameType => "CTF"; 6 | } 7 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Game/Gamemodes/GameControllerDM.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Server.Game 2 | { 3 | public class GameControllerDM : GameController 4 | { 5 | public override string GameType => "DM"; 6 | } 7 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Game/Gamemodes/GameControllerMod.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Server.Game 2 | { 3 | public class GameControllerMod : GameController 4 | { 5 | public override string GameType => "MOD"; 6 | } 7 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Game/TeeInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TeeSharp.Common.Enums; 3 | using TeeSharp.Common.Game; 4 | 5 | namespace TeeSharp.Server.Game 6 | { 7 | public class TeeInfo 8 | { 9 | public SkinPartParams this[SkinPart part] 10 | { 11 | get 12 | { 13 | switch (part) 14 | { 15 | case SkinPart.Body: 16 | return Body; 17 | case SkinPart.Marking: 18 | return Marking; 19 | case SkinPart.Decoration: 20 | return Decoration; 21 | case SkinPart.Hands: 22 | return Hands; 23 | case SkinPart.Feet: 24 | return Feet; 25 | case SkinPart.Eyes: 26 | return Eyes; 27 | default: 28 | throw new ArgumentOutOfRangeException(nameof(part), part, null); 29 | } 30 | } 31 | } 32 | 33 | public readonly SkinPartParams Body; 34 | public readonly SkinPartParams Marking; 35 | public readonly SkinPartParams Decoration; 36 | public readonly SkinPartParams Hands; 37 | public readonly SkinPartParams Feet; 38 | public readonly SkinPartParams Eyes; 39 | 40 | public TeeInfo() 41 | { 42 | Body = new SkinPartParams(); 43 | Marking = new SkinPartParams(); 44 | Decoration = new SkinPartParams(); 45 | Hands = new SkinPartParams(); 46 | Feet = new SkinPartParams(); 47 | Eyes = new SkinPartParams(); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Server/Abstract/BaseRegister.cs: -------------------------------------------------------------------------------- 1 | using System.Net.Sockets; 2 | using TeeSharp.Core; 3 | using TeeSharp.Network; 4 | 5 | namespace TeeSharp.Server 6 | { 7 | public abstract class BaseRegister : BaseInterface 8 | { 9 | public abstract void RegisterUpdate(AddressFamily netType); 10 | public abstract bool RegisterProcessPacket(Chunk packet, uint token); 11 | } 12 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Server/Abstract/BaseServerClient.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using TeeSharp.Common.Console; 3 | using TeeSharp.Common.Protocol; 4 | using TeeSharp.Common.Snapshots; 5 | using TeeSharp.Core; 6 | 7 | namespace TeeSharp.Server 8 | { 9 | public abstract class BaseServerClient : BaseInterface 10 | { 11 | public static readonly int MaxInputSize = SnapshotItemsInfo.GetSize() / sizeof(int); 12 | public const int MaxNameLength = 16; 13 | public const int MaxClanLength = 12; 14 | public const int MaxInputs = 200; 15 | public const int AuthedAdmin = 2; 16 | public const int AuthedModerator = 1; 17 | 18 | public virtual IEnumerator> SendCommandsEnumerator { get; set; } 19 | 20 | public class Input 21 | { 22 | public int Tick { get; set; } 23 | public readonly int[] Data; 24 | 25 | public Input() 26 | { 27 | Data = new int[MaxInputSize]; 28 | } 29 | } 30 | 31 | public virtual SnapshotRate SnapshotRate { get; set; } 32 | public virtual ServerClientState State { get; set; } 33 | public virtual int Latency { get; set; } 34 | public virtual int MapChunk { get; set; } 35 | public virtual int AuthTries { get; set; } 36 | 37 | /// 38 | /// 0 - non authed, 1 - moderator, 2 - admin 39 | /// 40 | public virtual int AccessLevel { get; set; } 41 | 42 | public virtual string Name { get; set; } 43 | public virtual string Clan { get; set; } 44 | public virtual int Country { get; set; } 45 | public virtual int Version { get; set; } 46 | 47 | public virtual int LastAckedSnapshot { get; set; } 48 | public virtual int LastInputTick { get; set; } 49 | 50 | public virtual bool Quitting { get; set; } 51 | public virtual SnapshotStorage SnapshotStorage { get; protected set; } 52 | public virtual Input[] Inputs { get; protected set; } 53 | public virtual Input LatestInput { get; protected set; } 54 | public virtual int CurrentInput { get; set; } 55 | 56 | public abstract void Reset(); 57 | } 58 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Server/ClientInfo.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Server 2 | { 3 | public class ClientInfo 4 | { 5 | public string Name { get; set; } 6 | public int Latency { get; set; } 7 | } 8 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Server/ClientVersion.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Server 2 | { 3 | public enum ClientVersion 4 | { 5 | VANILLA = 0, 6 | DDRACE = 1, 7 | DDNET_OLD = 2, 8 | DDNET_WHISPER = 217, 9 | DDNET_GOODHOOK = 221, 10 | DDNET_EXTRATUNES = 302, 11 | DDNET_RCONPROTECT = 408, 12 | DDNET_ANTIPING_PROJECTILE = 604, 13 | DDNET_HOOKDURATION_TUNE = 607, 14 | DDNET_FIREDELAY_TUNE = 701, 15 | DDNET_UPDATER_FIXED = 707, 16 | } 17 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Server/Register.cs: -------------------------------------------------------------------------------- 1 | using System.Net.Sockets; 2 | using TeeSharp.Network; 3 | 4 | namespace TeeSharp.Server 5 | { 6 | public class Register : BaseRegister 7 | { 8 | public override void RegisterUpdate(AddressFamily netType) 9 | { 10 | // ipv4 type == AddressFamily.InterNetwork 11 | // ipv6 type == AddressFamily.InterNetworkV6 12 | } 13 | 14 | public override bool RegisterProcessPacket(Chunk packet, uint token) 15 | { 16 | return false; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Server/ServerClient.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common.Snapshots; 2 | 3 | namespace TeeSharp.Server 4 | { 5 | public class ServerClient : BaseServerClient 6 | { 7 | public ServerClient() 8 | { 9 | State = ServerClientState.Empty; 10 | SnapshotStorage = new SnapshotStorage(); 11 | Inputs = new Input[MaxInputs]; 12 | LatestInput = new Input(); 13 | 14 | for (var i = 0; i < Inputs.Length; i++) 15 | { 16 | Inputs[i] = new Input() 17 | { 18 | Tick = -1, 19 | }; 20 | } 21 | } 22 | 23 | public override void Reset() 24 | { 25 | for (var i = 0; i < Inputs.Length; i++) 26 | { 27 | Inputs[i].Tick = -1; 28 | } 29 | 30 | CurrentInput = 0; 31 | LatestInput.Tick = 0; 32 | for (var i = 0; i < LatestInput.Data.Length; i++) 33 | LatestInput.Data[i] = 0; 34 | 35 | SnapshotStorage.PurgeAll(); 36 | LastAckedSnapshot = -1; 37 | LastInputTick = -1; 38 | SnapshotRate = SnapshotRate.Init; 39 | MapChunk = 0; 40 | AuthTries = 0; 41 | AccessLevel = 0; 42 | 43 | if (SendCommandsEnumerator != null) 44 | { 45 | SendCommandsEnumerator.Dispose(); 46 | SendCommandsEnumerator = null; 47 | } 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Server/ServerClientState.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Server 2 | { 3 | public enum ServerClientState 4 | { 5 | Empty = 0, 6 | Auth, 7 | Connecting, 8 | Ready, 9 | InGame, 10 | } 11 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Server/ServerKernelConfig.cs: -------------------------------------------------------------------------------- 1 | using TeeSharp.Common; 2 | using TeeSharp.Common.Config; 3 | using TeeSharp.Common.Game; 4 | using TeeSharp.Core; 5 | using TeeSharp.Network; 6 | using TeeSharp.Server.Game; 7 | using TeeSharp.Server.Game.Entities; 8 | 9 | namespace TeeSharp.Server 10 | { 11 | public class ServerKernelConfig : DefaultKernelConfig 12 | { 13 | public override void Load(IKernel kernel) 14 | { 15 | base.Load(kernel); 16 | 17 | kernel.Bind().To().AsSingleton(); 18 | kernel.Bind().To().AsSingleton(); 19 | kernel.Bind().To().AsSingleton(); 20 | kernel.Bind().To().AsSingleton(); 21 | kernel.Bind().To().AsSingleton(); 22 | kernel.Bind().To().AsSingleton(); 23 | kernel.Bind().To().AsSingleton(); 24 | kernel.Bind().To().AsSingleton(); 25 | kernel.Bind().To().AsSingleton(); 26 | kernel.Bind().To().AsSingleton(); 27 | 28 | kernel.Bind().To(); 29 | kernel.Bind().To(); 30 | kernel.Bind().To(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /TeeSharp.Server/src/Server/SnapshotRate.cs: -------------------------------------------------------------------------------- 1 | namespace TeeSharp.Server 2 | { 3 | public enum SnapshotRate 4 | { 5 | Init = 0, 6 | Full, 7 | Recover 8 | } 9 | } -------------------------------------------------------------------------------- /TeeSharp.Tests/TeeSharp.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | 6 | false 7 | 8 | 7.2 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /TeeSharp.Tests/src/BidirectionalListTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using TeeSharp.Core; 4 | 5 | namespace TeeSharp.Tests 6 | { 7 | [TestClass] 8 | public class BidirectionalListTests 9 | { 10 | [TestMethod] 11 | public void TestInsert() 12 | { 13 | var list = BidirectionalList.New(); 14 | var node1 = list.Add(1); 15 | var node2 = list.Add(2); 16 | var node3 = list.Add(3); 17 | var node4 = list.Add(4); 18 | var node5 = list.Add(5); 19 | 20 | foreach (var i in list) Console.Write($"{i} "); Console.Write('\n'); 21 | list.RemoveFast(node5); 22 | foreach (var i in list) Console.Write($"{i} "); Console.Write('\n'); 23 | list.RemoveFast(node4); 24 | foreach (var i in list) Console.Write($"{i} "); Console.Write('\n'); 25 | list.RemoveFast(node3); 26 | foreach (var i in list) Console.Write($"{i} "); Console.Write('\n'); 27 | list.RemoveFast(node2); 28 | foreach (var i in list) Console.Write($"{i} "); Console.Write('\n'); 29 | list.RemoveFast(node1); 30 | foreach (var i in list) Console.Write($"{i} "); Console.Write('\n'); 31 | 32 | Assert.AreSame(null, list.First); 33 | Assert.AreSame(null, list.Last); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /TeeSharp.Tests/src/CommonTests.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using TeeSharp.Core; 3 | using TeeSharp.Core.Extensions; 4 | 5 | namespace TeeSharp.Tests 6 | { 7 | [TestClass] 8 | public class CommonTests 9 | { 10 | [TestMethod] 11 | public void TestIntsToStr() 12 | { 13 | const int arraySize = 4; 14 | var actual = new int[arraySize] 15 | { 16 | -723130889, -269292316, -204868660, -269032192 17 | }.IntsToStr(); 18 | Assert.IsTrue(actual == "TeeworldsIsLoveeeeee".Limit(sizeof(int) * arraySize - 1)); // Max string length (sizeof(int) * 4 - 1 19 | } 20 | 21 | [TestMethod] 22 | public void TestStrToInt() 23 | { 24 | var actual = "wL7SHc4Ipa1prqHE".StrToInts(4); 25 | var expected = new int[] 26 | { 27 | -137578541, -924601143, -253644304, -219035648 28 | }; 29 | 30 | CollectionAssert.AreEqual(expected, actual); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /TeeSharp.Tests/src/ContainerTests.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using TeeSharp.Core.IoC; 4 | using TeeSharp.Network; 5 | using TeeSharp.Network.Extensions; 6 | 7 | namespace TeeSharp.Tests 8 | { 9 | [TestClass] 10 | public class ContainerTests 11 | { 12 | private class TestBaseClass 13 | { 14 | } 15 | 16 | private class TestClass : TestBaseClass 17 | { 18 | } 19 | 20 | [TestMethod] 21 | public void TestContainerSingletone() 22 | { 23 | var container = new Container(); 24 | container.Register(typeof(TestClass)).AsSingleton(); 25 | 26 | Assert.AreSame( 27 | container.Resolve(), 28 | container.Resolve() 29 | ); 30 | } 31 | 32 | [TestMethod] 33 | public void TestContainerScope() 34 | { 35 | var container = new Container(); 36 | container.Register(typeof(TestClass)).PerScope(); 37 | 38 | var instance1 = container.Resolve(); 39 | var instance2 = container.Resolve(); 40 | 41 | Assert.AreEqual(instance1, instance2); 42 | 43 | using (var scope = container.CreateScope()) 44 | { 45 | var instance3 = scope.Resolve(); 46 | var instance4 = scope.Resolve(); 47 | 48 | Assert.AreEqual(instance3, instance4); 49 | Assert.AreNotEqual(instance1, instance3); 50 | } 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /TeeSharp.Tests/src/NetworkTests.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using TeeSharp.Network; 4 | using TeeSharp.Network.Extensions; 5 | 6 | namespace TeeSharp.Tests 7 | { 8 | [TestClass] 9 | public class NetworkTests 10 | { 11 | [TestMethod] 12 | public void TestIPv4EndPointSerialize() 13 | { 14 | var endPoint1 = new IPEndPoint(IPAddress.Parse("192.168.42.5"), 65202); 15 | var buf1 = new byte[] {1, 0, 0, 0, 192, 168, 42, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 178, 254, 0, 0}; 16 | var buf2 = endPoint1.Raw(); 17 | CollectionAssert.AreEqual(buf1, buf2); 18 | 19 | // TODO for IPv6 20 | //var endPoint2 = new IPEndPoint(IPAddress.Parse("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), 65202); 21 | // var buf3 = endPoint2.Raw(); 22 | } 23 | 24 | [TestMethod] 25 | public void TestHash() 26 | { 27 | var endPoint1 = new IPEndPoint(IPAddress.Parse("192.168.42.5"), 65202); 28 | var buf2 = endPoint1.Raw(); 29 | var hash = Network.NetworkHelper.Hash(buf2); 30 | 31 | Assert.AreEqual(hash, 1578705565u); 32 | } 33 | 34 | [TestMethod] 35 | public void TestEndPointRaw() 36 | { 37 | var endPoint1 = new IPEndPoint(IPAddress.Parse("192.168.137.106"), 51850); 38 | var actual = endPoint1.Raw(); 39 | var expected = new byte[] 40 | { 41 | 1, 0, 0, 0, 192, 168, 137, 106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 202, 0, 0 42 | }; 43 | CollectionAssert.AreEqual(expected, actual); 44 | } 45 | 46 | [TestMethod] 47 | public void TestEquals() 48 | { 49 | var endPoint1 = new IPEndPoint(IPAddress.Parse("192.168.137.106"), 51850); 50 | var endPoint2 = new IPEndPoint(IPAddress.Parse("192.168.137.106"), 51850); 51 | 52 | Assert.IsTrue(endPoint1.Compare(endPoint2, true)); 53 | } 54 | 55 | [TestMethod] 56 | public void TestGenerateToken() 57 | { 58 | var endPoint1 = new IPEndPoint(IPAddress.Parse("192.168.137.106"), 51850); 59 | var token = TokenHelper.GenerateToken(endPoint1, 65141430699971723); 60 | Assert.AreEqual(token, 2189052134u); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /res/TeeSharp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Matodor/TeeSharp/df6ac231b2bfcadbfaf953f03cef93eff709f52e/res/TeeSharp.png --------------------------------------------------------------------------------