├── .gitattributes ├── .gitignore ├── .travis.yml ├── CONTRIBUTORS ├── CoCSharp.sln ├── LICENSE ├── README.md ├── benchmarks ├── App.config ├── BenchmarkResult.cs ├── BenchmarkTest.cs ├── Benchmarker.cs ├── Benchmarks.csproj ├── Content │ ├── buildings.csv │ ├── decos.csv │ ├── obstacles.csv │ ├── traps.csv │ ├── village.json │ └── village_max.json ├── Program.cs ├── Properties │ └── AssemblyInfo.cs └── Test │ ├── CsvConvert_Deserialize.cs │ ├── CsvData_GetInstance.cs │ ├── VillageObject_AddComponent.cs │ ├── Village_FromJson1.cs │ ├── Village_FromJson2.cs │ ├── Village_ToJson1.cs │ └── Village_ToJson2.cs ├── scripts ├── csv_deomp.sh ├── decomp_characters_properties.txt ├── decomp_spells_properties.txt ├── gen_csv_properties.py └── hexstr_to_csharparray.py ├── src ├── CoCSharp.Client │ ├── App.config │ ├── Client.cs │ ├── CoCSharp.Client.csproj │ ├── Program.cs │ └── Properties │ │ └── AssemblyInfo.cs ├── CoCSharp.Proxy │ ├── App.config │ ├── Client.cs │ ├── CoCSharp.Proxy.csproj │ ├── CommandMapper.cs │ ├── MessageDumper.cs │ ├── MessageLogger.cs │ ├── MessageMapper.cs │ ├── MessageProcessorNaClProxy.cs │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Proxy.cs │ └── packages.config ├── CoCSharp.Server.Api │ ├── Chatting │ │ ├── ChatCommand.cs │ │ ├── IChatCommand.cs │ │ └── IChatManager.cs │ ├── CoCSharp.Server.API.csproj │ ├── CoCSharp.Server.Api.csproj │ ├── Core │ │ ├── Factories │ │ │ ├── ClanSaveFactory.cs │ │ │ └── LevelSaveFactory.cs │ │ ├── FactoryManager.cs │ │ ├── ICacheManager.cs │ │ ├── IClanManager.cs │ │ ├── IFactory.cs │ │ ├── IFactoryManager.cs │ │ ├── IFactory{T}.cs │ │ ├── ILevelManager.cs │ │ └── IMessageHandler.cs │ ├── Db │ │ ├── ClanQuery.cs │ │ ├── ClanSave.cs │ │ ├── IDbManager.cs │ │ └── LevelSave.cs │ ├── Events │ │ └── Server │ │ │ ├── ServerConnectionEventArgs.cs │ │ │ └── ServerEventArgs.cs │ ├── IClient.cs │ ├── IServer.cs │ ├── IServerConfiguration.cs │ ├── Logging │ │ ├── ErrorLogger.cs │ │ ├── InfoLogger.cs │ │ ├── Logger.cs │ │ ├── Logs.cs │ │ └── WarnLogger.cs │ └── Properties │ │ └── AssemblyInfo.cs ├── CoCSharp.Server │ ├── App.config │ ├── Chatting │ │ ├── ChatManager.cs │ │ └── Commands │ │ │ ├── ChangeLogChatCommand.cs │ │ │ ├── HelpChatCommand.cs │ │ │ └── StatisticsChatCommand.cs │ ├── Client.cs │ ├── CoCSharp.Server.csproj │ ├── Core │ │ ├── CacheManager.cs │ │ ├── ClanManager.cs │ │ ├── ClientCollection.cs │ │ ├── LevelManager.cs │ │ ├── MessageHandler.cs │ │ └── SaveQueue{T}.cs │ ├── Db │ │ ├── MySqlCommandExtensions.cs │ │ ├── MySqlDbManager.Clan.cs │ │ ├── MySqlDbManager.Level.cs │ │ ├── MySqlDbManager.cs │ │ ├── MySqlDbManagerQueries.Designer.cs │ │ ├── MySqlDbManagerQueries.resx │ │ └── MySqlTemplate.cs │ ├── Logging │ │ ├── ClanLogger.cs │ │ └── CleanErrorLogger.cs │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── README.md │ ├── RemoteSession.cs │ ├── Server.Listening.cs │ ├── Server.cs │ ├── ServerConfiguration.cs │ ├── SocketAsyncEventArgsPool.cs │ ├── Utils.cs │ ├── WebApi.cs │ ├── contents │ │ ├── changelog │ │ ├── cocsharp.mysql │ │ ├── level │ │ │ ├── npc1.json │ │ │ ├── npc10.json │ │ │ ├── npc11.json │ │ │ ├── npc12.json │ │ │ ├── npc13.json │ │ │ ├── npc14.json │ │ │ ├── npc15.json │ │ │ ├── npc16.json │ │ │ ├── npc17.json │ │ │ ├── npc18.json │ │ │ ├── npc19.json │ │ │ ├── npc2.json │ │ │ ├── npc20.json │ │ │ ├── npc21.json │ │ │ ├── npc22.json │ │ │ ├── npc23.json │ │ │ ├── npc24.json │ │ │ ├── npc25.json │ │ │ ├── npc26.json │ │ │ ├── npc27.json │ │ │ ├── npc28.json │ │ │ ├── npc29.json │ │ │ ├── npc3.json │ │ │ ├── npc30.json │ │ │ ├── npc31.json │ │ │ ├── npc32.json │ │ │ ├── npc33.json │ │ │ ├── npc34.json │ │ │ ├── npc35.json │ │ │ ├── npc36.json │ │ │ ├── npc37.json │ │ │ ├── npc38.json │ │ │ ├── npc39.json │ │ │ ├── npc4.json │ │ │ ├── npc40.json │ │ │ ├── npc41.json │ │ │ ├── npc42.json │ │ │ ├── npc43.json │ │ │ ├── npc44.json │ │ │ ├── npc45.json │ │ │ ├── npc46.json │ │ │ ├── npc47.json │ │ │ ├── npc48.json │ │ │ ├── npc5.json │ │ │ ├── npc6.json │ │ │ ├── npc7.json │ │ │ ├── npc8.json │ │ │ └── npc9.json │ │ ├── starting_village.json │ │ └── welcome │ └── packages.config └── CoCSharp │ ├── CoCSharp.csproj │ ├── CoCSharp.csproj.user │ ├── Csv │ ├── Compression │ │ ├── Common │ │ │ ├── CRC.cs │ │ │ ├── CommandLineParser.cs │ │ │ ├── InBuffer.cs │ │ │ └── OutBuffer.cs │ │ ├── Compress │ │ │ ├── LZ │ │ │ │ ├── IMatchFinder.cs │ │ │ │ ├── LzBinTree.cs │ │ │ │ ├── LzInWindow.cs │ │ │ │ └── LzOutWindow.cs │ │ │ ├── LZMA │ │ │ │ ├── LzmaBase.cs │ │ │ │ ├── LzmaDecoder.cs │ │ │ │ └── LzmaEncoder.cs │ │ │ └── RangeCoder │ │ │ │ ├── RangeCoder.cs │ │ │ │ ├── RangeCoderBit.cs │ │ │ │ └── RangeCoderBitTree.cs │ │ ├── ICoder.cs │ │ └── README.txt │ ├── CsvAliasAttribute.cs │ ├── CsvAttributeHelper.cs │ ├── CsvConvert.cs │ ├── CsvData.cs │ ├── CsvDataColumn.cs │ ├── CsvDataColumnCollection.cs │ ├── CsvDataRow.cs │ ├── CsvDataRowCollection.cs │ ├── CsvDataRowCollection{T}.cs │ ├── CsvDataRowRef.cs │ ├── CsvDataRow{T}.cs │ ├── CsvDataTable.cs │ ├── CsvDataTableCollection.cs │ ├── CsvDataTable{T}.cs │ ├── CsvException.cs │ ├── CsvIgnoreAttribute.cs │ ├── CsvTable.cs │ ├── CsvTableCompression.cs │ ├── ObjectMapper.cs │ └── PropertyMap.cs │ ├── Data │ ├── AssetDownloadCompletedEventArgs.cs │ ├── AssetDownloadProgressChangedEventArgs.cs │ ├── AssetDownloader.cs │ ├── AssetManager.cs │ ├── AssetProvider.cs │ ├── AssetProviders │ │ └── CsvDataTableAssetProvider.cs │ ├── Fingerprint.cs │ ├── FingerprintFile.cs │ ├── MessageReaderWriterExt.cs │ ├── Models │ │ ├── BuildingData.cs │ │ ├── CharacterData.cs │ │ ├── DecorationData.cs │ │ ├── ExperienceLevelData.cs │ │ ├── GlobalData.cs │ │ ├── ObstacleData.cs │ │ ├── ResourceData.cs │ │ └── TrapData.cs │ ├── Slot.cs │ ├── SlotCollection{T}.cs │ ├── Slots │ │ ├── AchievementProgessSlot.cs │ │ ├── AchievementSlot.cs │ │ ├── AllianceUnitSlot.cs │ │ ├── HeroHealthSlot.cs │ │ ├── HeroStateSlot.cs │ │ ├── HeroUpgradeSlot.cs │ │ ├── NpcElixirSlot.cs │ │ ├── NpcGoldSlot.cs │ │ ├── NpcStarSlot.cs │ │ ├── ResourceAmountSlot.cs │ │ ├── ResourceCapacitySlot.cs │ │ ├── SpellSlot.cs │ │ ├── SpellUpgradeSlot.cs │ │ ├── TutorialProgressSlot.cs │ │ ├── UnitSlot.cs │ │ ├── UnitUpgradeSlot.cs │ │ └── UnknownSlot.cs │ └── Slot{T}.cs │ ├── InternalConstants.cs │ ├── InternalUtils.cs │ ├── Logic │ ├── Avatar.cs │ ├── Buildable{T}.cs │ ├── Building.cs │ ├── Clan.cs │ ├── ClanMember.cs │ ├── ClanMemberRole.cs │ ├── ClearingFinishedEventArgs.cs │ ├── Command.cs │ ├── CommandException.cs │ ├── CommandFactory.cs │ ├── CommandFactorySuppressAttribute.cs │ ├── Commands │ │ ├── AllianceJoinedCommand.cs │ │ ├── AllianceLeftCommand.cs │ │ ├── AllianceRoleUpdatedCommand.cs │ │ ├── AllianceSettingChangedCommand.cs │ │ ├── AvatarNameChangedCommand.cs │ │ ├── BuyBuildingCommand.cs │ │ ├── BuyDecorationCommand.cs │ │ ├── BuyResourcesCommand.cs │ │ ├── BuyTrapCommand.cs │ │ ├── CancelConsturctionCommand.cs │ │ ├── CastSpellCommand.cs │ │ ├── ClearObstacleCommand.cs │ │ ├── FreeWorkerCommand.cs │ │ ├── MatchmakingCommand.cs │ │ ├── MoveMultipleVillageObjectCommand.cs │ │ ├── MoveVillageObjectCommand.cs │ │ ├── PlaceAttackerCommand.cs │ │ ├── RearmTrapCommand.cs │ │ ├── RemoveShieldCommand.cs │ │ ├── SellDecorationCommand.cs │ │ ├── SpeedUpConstructionCommand.cs │ │ ├── TrainUnitCommand.cs │ │ ├── UnlockBuildingCommand.cs │ │ ├── UpgradeBuildableCommand.cs │ │ ├── UpgradeMultipleBuildableCommand.cs │ │ └── UpgradeUnitCommand.cs │ ├── Component.cs │ ├── ComponentPool.cs │ ├── Components │ │ └── UnitProductionComponent.cs │ ├── Decoration.cs │ ├── InvalidCommandException.cs │ ├── Level.cs │ ├── LevelLog.cs │ ├── LogicUtils.cs │ ├── Obstacle.cs │ ├── Session.cs │ ├── SessionState.cs │ ├── TickTimer.cs │ ├── Trap.cs │ ├── Village.Json.cs │ ├── Village.cs │ ├── VillageObject.cs │ ├── VillageObjectCollection.cs │ ├── VillageObjectPool.cs │ ├── VillageObject{T}.cs │ └── WorkerManager.cs │ ├── Network │ ├── BufferStream.cs │ ├── Cryptography │ │ ├── CoCCrypto.cs │ │ ├── Crypto7.cs │ │ ├── Crypto8.cs │ │ ├── NaCl │ │ │ ├── Internal │ │ │ │ ├── Blake2 │ │ │ │ │ ├── Blake2B.FullyUnrolled.cs │ │ │ │ │ └── Blake2B.cs │ │ │ │ ├── curve25519.cs │ │ │ │ ├── curve25519xsalsa20poly1305.cs │ │ │ │ ├── hsalsa20.cs │ │ │ │ ├── poly1305.cs │ │ │ │ ├── salsa20.cs │ │ │ │ ├── verify_16.cs │ │ │ │ ├── xsalsa20.cs │ │ │ │ └── xsalsa20poly1305.cs │ │ │ ├── KeyPair.cs │ │ │ ├── PublicKeyBox.cs │ │ │ └── SecretBox.cs │ │ └── UpdateNonceType.cs │ ├── DisconnectedEventArgs.cs │ ├── InvalidMessageException.cs │ ├── Memory │ │ ├── MemoryBlock.cs │ │ ├── MemoryBlockPool.cs │ │ ├── MemorySlab.cs │ │ └── MemorySlabsStream.cs │ ├── Message.cs │ ├── MessageBufferManager.cs │ ├── MessageComponent.cs │ ├── MessageDirection.cs │ ├── MessageException.cs │ ├── MessageFactory.cs │ ├── MessageFactorySuppressAttribute.cs │ ├── MessageHeader.cs │ ├── MessageProcessor.cs │ ├── MessageProcessorNaCl.cs │ ├── MessageProcessorRC4.cs │ ├── MessageReader.cs │ ├── MessageReceivedEventArgs.cs │ ├── MessageSentEventArgs.cs │ ├── MessageToken.cs │ ├── MessageWriter.cs │ ├── Messages │ │ ├── AllianceChangeRoleMessage.cs │ │ ├── AllianceChangeRoleOkMessage.cs │ │ ├── AllianceChatMessage.cs │ │ ├── AllianceDataRequestMessage.cs │ │ ├── AllianceDataResponseMessage.cs │ │ ├── AllianceFullEntryMessage.cs │ │ ├── AllianceSearchRequestMessage.cs │ │ ├── AllianceSearchResponseMessage.cs │ │ ├── AllianceStreamEntry.cs │ │ ├── AllianceStreamEventMessage.cs │ │ ├── AllianceStreamMessage.cs │ │ ├── AttackLogAvatarStreamEntry.cs │ │ ├── AttackNpcMessage.cs │ │ ├── AvailableServerCommandMessage.cs │ │ ├── AvatarMessageComponent.cs │ │ ├── AvatarProfileRequestMessage.cs │ │ ├── AvatarProfileResponseMessage.cs │ │ ├── AvatarRankingEntryMessageComponent.cs │ │ ├── AvatarRankingsListRequestMessage.cs │ │ ├── AvatarRankingsListResponseMessage.cs │ │ ├── AvatarStreamEntry.cs │ │ ├── AvatarStreamMessage.cs │ │ ├── ChangeAllianceSettingMessage.cs │ │ ├── ChangeAvatarNameRequestMessage.cs │ │ ├── ChatAllianceStreamEntry.cs │ │ ├── ChatMessageClientMessage.cs │ │ ├── ChatMessageServerMessage.cs │ │ ├── ClanCompleteMessageComponent.cs │ │ ├── ClanMemberMessageComponent.cs │ │ ├── ClanMessageComponent.cs │ │ ├── CommandMessage.cs │ │ ├── CreateAllianceMessage.cs │ │ ├── DefenseLogAvatarStreamEntry.cs │ │ ├── EncryptionMessage.cs │ │ ├── EnemyHomeDataMessage.cs │ │ ├── HandshakeRequestMessage.cs │ │ ├── HandshakeSuccessMessage.cs │ │ ├── JoinAllianceMessage.cs │ │ ├── JoinableAllianceListRequestMessage.cs │ │ ├── JoinableAllianceListResponseMessage.cs │ │ ├── JoinedOrLeftAllianceStream.cs │ │ ├── KeepAliveRequestMessage.cs │ │ ├── KeepAliveResponseMessage.cs │ │ ├── LeaveAllianceMessage.cs │ │ ├── LoginFailedMessage.cs │ │ ├── LoginRequestMessage.cs │ │ ├── LoginSuccessMessage.cs │ │ ├── MoveVillageObjectMessageComponent.cs │ │ ├── NpcDataMessage.cs │ │ ├── OwnHomeDataMessage.cs │ │ ├── ReplayAllianceStreamEntry.cs │ │ ├── ReturnHomeMessage.cs │ │ ├── ServerErrorMessage.cs │ │ ├── ServerShutdownInfoMessage.cs │ │ ├── StreamEntry.cs │ │ ├── Unknown11AllianceStreamEntry.cs │ │ ├── UnknownMessage.cs │ │ ├── VillageMessageComponent.cs │ │ ├── VisitHomeDataMessage.cs │ │ └── VisitHomeMessage.cs │ ├── NetworkManagerAsync.cs │ ├── NetworkManagerAsyncSettings.cs │ ├── NetworkManagerAsyncStatistics.cs │ ├── SocketAsyncEventArgsPool.cs │ ├── StreamEntryFactory.cs │ └── StreamEntrySuppressAttribute.cs │ ├── Pool.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── TimeUtils.cs │ ├── TokenUtils.cs │ ├── backup.csproj │ └── packages.config └── tests ├── Csv ├── CsvConvertTests.cs ├── CsvDataColumnCollectionTests.cs ├── CsvDataRowCollectionTests.cs ├── CsvDataRowRefTests.cs ├── CsvDataRowTests.cs ├── CsvDataTableCollectionTests.cs ├── CsvDataTableTests.cs ├── CsvTableTests.cs └── TestData.cs ├── Data ├── AssetDownloaderTests.cs ├── AssetManagerTests.cs ├── AssetProviders │ └── CsvDataTableAssetProviderTests.cs ├── FingerprintTests.cs └── SlotCollectionTests.cs ├── Logic ├── BuildingTests.cs ├── LevelTests.cs ├── TickTimerTests.cs ├── VillageObjectCollectionTests.cs └── VillageTests.cs ├── Network ├── BufferStreamTests.cs ├── CommandFactoryTests.cs ├── MessageBufferManagerTests.cs ├── MessageFactoryTests.cs ├── MessageReaderTests.cs ├── MessageTests.cs ├── MessageWriterTests.cs ├── Messages │ └── Commands │ │ └── BuyResourcesCommandTests.cs └── SocketAsyncEventArgsPoolTests.cs ├── Properties └── AssemblyInfo.cs ├── TestUtils.cs ├── Tests.csproj ├── TokenUtilsTests.cs ├── contents ├── csv │ ├── buildings.csv │ ├── com_buildings.csv │ ├── decos.csv │ ├── obstacles.csv │ ├── resources.csv │ └── traps.csv ├── fingerprint.json └── layouts │ ├── buildings │ ├── no_data.json │ ├── no_lvl.json │ ├── no_x.json │ └── no_y.json │ ├── exp_ver.json │ ├── no_townhall.json │ ├── starting_home.json │ ├── test_village.json │ ├── village_buildings1.json │ └── village_buildings2.json └── packages.config /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Content 5 | *.csv binary 6 | 7 | # Custom for Visual Studio 8 | *.cs diff=csharp 9 | *.sln merge=union 10 | *.csproj merge=union 11 | *.vbproj merge=union 12 | *.fsproj merge=union 13 | *.dbproj merge=union 14 | 15 | # Standard to msysgit 16 | *.doc diff=astextplain 17 | *.DOC diff=astextplain 18 | *.docx diff=astextplain 19 | *.DOCX diff=astextplain 20 | *.dot diff=astextplain 21 | *.DOT diff=astextplain 22 | *.pdf diff=astextplain 23 | *.PDF diff=astextplain 24 | *.rtf diff=astextplain 25 | *.RTF diff=astextplain 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prefs 2 | *.suo 3 | *.vsp 4 | 5 | # Build 6 | bin/ 7 | obj/ 8 | .vscode/ 9 | .vs/ 10 | 11 | # Nuget 12 | packages/ 13 | 14 | # Vim 15 | *~ 16 | *.swo 17 | *.swp 18 | *.swn 19 | *.swm 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: csharp 2 | solution: CoCSharp.sln 3 | 4 | mono: 5 | - latest 6 | 7 | install: 8 | - nuget restore ./src/CoCSharp.sln 9 | - nuget install NUnit.Runners -Version 3.5.0 -OutputDirectory nunitrunner 10 | 11 | script: 12 | - xbuild ./src/CoCSharp.sln 13 | - mono ./nunitrunner/NUnit.Console.3.5.0/tools/nunit3-console.exe ./src/CoCSharp.Test/bin/Debug/CoCSharp.Test.dll 14 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | Thanks to those guys. =] 2 | 3 | FICTURE7 - Wrote most of the code. 4 | castelbuilder123 - Wrote most of the client plugin API. 5 | circa94 - Helped with message implementations. 6 | Filippo - Helped with message implementations. 7 | devinvisible - Corrected typos and resolved warnings. 8 | yschua - Helped with message implementations. 9 | buddyfavors - Helped with message implementations. 10 | Aidid - Helped with message implementations. 11 | 12 | The MVPs 13 | 14 | clanner - Making the Clash of Clans Documentation Project and 7.x.x encryption. 15 | clugh - Cracking of the 8.x.x encryption. Some says he's Batman, he appears only in the darkest night, when he is most needed. 16 | Ultrapowa - Making of UCS which got me interested in how it worked. 17 | Patrik - Provided a test server and did some important concurrency tests to make a better server. 18 | 19 | And of course all of you who starred the project and encouraged me. 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 FICTURE7 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /benchmarks/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /benchmarks/BenchmarkResult.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Benchmark 2 | { 3 | public class BenchmarkResult 4 | { 5 | public BenchmarkResult(string name, int count, double duration) 6 | { 7 | Name = name; 8 | Count = count; 9 | Duration = duration; 10 | } 11 | 12 | public string Name { get; set; } 13 | public int Count { get; set; } 14 | public double Duration { get; set; } 15 | public double Average 16 | { 17 | get 18 | { 19 | return Duration / Count; 20 | } 21 | } 22 | 23 | public override string ToString() 24 | { 25 | return string.Format("{{{0}}}:({{{1}ms}},{{{2}ms}})", Name, Duration, Average); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /benchmarks/BenchmarkTest.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Benchmark 2 | { 3 | public abstract class BenchmarkTest 4 | { 5 | public const int DefaultCount = 100000; 6 | 7 | // Name of the test. 8 | public virtual string Name { get; } 9 | 10 | // Amount of time to run the test. 11 | public virtual int Count 12 | { 13 | get 14 | { 15 | return DefaultCount; 16 | } 17 | } 18 | 19 | // Code to run before a test is run completely. 20 | public virtual void OneTimeSetUp() 21 | { 22 | // Space 23 | } 24 | 25 | // Code to run each time before a test is run. 26 | public virtual void SetUp() 27 | { 28 | // Space 29 | } 30 | 31 | // Code to run after a test is run completely. 32 | public virtual void OneTimeTearDown() 33 | { 34 | // Space 35 | } 36 | 37 | // Code to run each time after a test is run. 38 | public virtual void TearDown() 39 | { 40 | // Space 41 | } 42 | 43 | // Code to run. 44 | public abstract void Execute(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /benchmarks/Benchmarker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | 4 | namespace CoCSharp.Benchmark 5 | { 6 | public class Benchmarker 7 | { 8 | public Benchmarker() 9 | { 10 | _sw = new Stopwatch(); 11 | } 12 | 13 | private readonly Stopwatch _sw; 14 | 15 | public BenchmarkResult Run() where T : BenchmarkTest, new() 16 | { 17 | var instance = new T(); 18 | var type = typeof(T); 19 | 20 | var name = instance.Name == null ? type.Name.Replace("_", ".") : instance.Name; 21 | var count = instance.Count; 22 | var shouldOneTimeSetUp = type.GetMethod("OneTimeSetUp").DeclaringType == type; 23 | var shouldSetUp = type.GetMethod("SetUp").DeclaringType == type; 24 | var shouldOneTimeTearDown = type.GetMethod("OneTimeTearDown").DeclaringType == type; 25 | var shouldTearDown = type.GetMethod("TearDown").DeclaringType == type; 26 | 27 | Console.WriteLine(name + ":" + count); 28 | 29 | if (shouldOneTimeSetUp) 30 | instance.OneTimeSetUp(); 31 | 32 | for (int i = 0; i < count; i++) 33 | { 34 | if (shouldSetUp) 35 | instance.SetUp(); 36 | 37 | _sw.Start(); 38 | instance.Execute(); 39 | _sw.Stop(); 40 | 41 | if (shouldTearDown) 42 | instance.TearDown(); 43 | } 44 | 45 | if (shouldOneTimeTearDown) 46 | instance.OneTimeTearDown(); 47 | 48 | var result = new BenchmarkResult(name, count, _sw.Elapsed.TotalMilliseconds); 49 | Console.WriteLine("\t-> Duration {0}ms\r\n\t-> Average {1}ms", result.Duration, result.Average); 50 | return result; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /benchmarks/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CoCSharp.Benchmark")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CoCSharp.Benchmark")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("eacf0ae5-d485-41c4-a164-bb5268d45cc3")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /benchmarks/Test/CsvConvert_Deserialize.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Csv; 2 | using CoCSharp.Data.Models; 3 | using System; 4 | 5 | namespace CoCSharp.Benchmark.Test 6 | { 7 | public class CsvConvert_Deserialize : BenchmarkTest 8 | { 9 | public CsvConvert_Deserialize() 10 | { 11 | _table = new CsvTable("Content/buildings.csv"); 12 | } 13 | 14 | public override int Count 15 | { 16 | get 17 | { 18 | return 5000; 19 | } 20 | } 21 | 22 | private readonly CsvTable _table; 23 | 24 | public override void Execute() 25 | { 26 | CsvConvert.Deserialize(_table, typeof(BuildingData)); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /benchmarks/Test/CsvData_GetInstance.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Csv; 2 | using CoCSharp.Data.Models; 3 | 4 | namespace CoCSharp.Benchmark.Test 5 | { 6 | public class CsvData_GetInstance : BenchmarkTest 7 | { 8 | public CsvData_GetInstance() 9 | { 10 | var instance = CsvData.GetInstance(); 11 | } 12 | 13 | public override void Execute() 14 | { 15 | CsvData.GetInstance(); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /benchmarks/Test/VillageObject_AddComponent.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Csv; 2 | using CoCSharp.Data; 3 | using CoCSharp.Data.Models; 4 | using CoCSharp.Logic; 5 | using CoCSharp.Logic.Components; 6 | 7 | namespace CoCSharp.Benchmark.Test 8 | { 9 | public class VillageObject_AddComponent : BenchmarkTest 10 | { 11 | private readonly Village _village; 12 | private Building _building; 13 | 14 | public override void SetUp() 15 | { 16 | //var table = AssetManager.Default.Get>(); 17 | //var data = table.Rows[0][0]; 18 | //_building = new Building(_village, data); 19 | } 20 | 21 | public override void Execute() 22 | { 23 | //_building.AddComponent(); 24 | //_building.AddComponent(UnitProductionComponent.ID); 25 | _building.AddComponent(new UnitProductionComponent()); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /benchmarks/Test/Village_FromJson1.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Logic; 2 | using System.IO; 3 | 4 | namespace CoCSharp.Benchmark.Test 5 | { 6 | public class Village_FromJson1 : BenchmarkTest 7 | { 8 | public Village_FromJson1() 9 | { 10 | var path = "Content\\village.json"; 11 | _villageJson = File.ReadAllText(path); 12 | } 13 | 14 | private readonly string _villageJson; 15 | private Village _village; 16 | 17 | public override void Execute() 18 | { 19 | _village = Village.FromJson(_villageJson); 20 | } 21 | 22 | public override void TearDown() 23 | { 24 | _village.Dispose(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /benchmarks/Test/Village_FromJson2.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Logic; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | 7 | namespace CoCSharp.Benchmark.Test 8 | { 9 | public class Village_FromJson2 : BenchmarkTest 10 | { 11 | public Village_FromJson2() 12 | { 13 | var path = "Content\\village_max.json"; 14 | _villageJson = File.ReadAllText(path); 15 | _refs = new List(); 16 | } 17 | 18 | private readonly string _villageJson; 19 | 20 | //public override int Count 21 | //{ 22 | // get 23 | // { 24 | // return 500; 25 | // } 26 | //} 27 | 28 | private List _refs; 29 | private Village _village; 30 | 31 | 32 | public override void Execute() 33 | { 34 | _village = Village.FromJson(_villageJson); 35 | } 36 | 37 | public override void TearDown() 38 | { 39 | _refs.Add(new WeakReference(_village)); 40 | _village.Dispose(); 41 | } 42 | 43 | public override void OneTimeTearDown() 44 | { 45 | Console.WriteLine("Created: {0}", VillageObject.s_totalCreated); 46 | Console.WriteLine("Rested: {0}", VillageObject.s_totalReseted); 47 | Console.WriteLine("InPool: {0}", VillageObjectPool.TotalCount); 48 | Console.WriteLine("Alive: {0}", _refs.Count(r => r.IsAlive)); 49 | 50 | _village = null; 51 | Console.WriteLine("\r\nGC.Collect()\r\n"); 52 | GC.Collect(); 53 | 54 | Console.WriteLine("Created: {0}", VillageObject.s_totalCreated); 55 | Console.WriteLine("Rested: {0}", VillageObject.s_totalReseted); 56 | Console.WriteLine("InPool: {0}", VillageObjectPool.TotalCount); 57 | Console.WriteLine("Alive: {0}", _refs.Count(r => r.IsAlive)); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /benchmarks/Test/Village_ToJson1.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Csv; 2 | using CoCSharp.Data; 3 | using CoCSharp.Data.Models; 4 | using CoCSharp.Logic; 5 | 6 | namespace CoCSharp.Benchmark.Test 7 | { 8 | public class Village_ToJson1 : BenchmarkTest 9 | { 10 | public Village_ToJson1() 11 | { 12 | var manager = AssetManager.Default; 13 | _village = new Village(); 14 | 15 | var table = manager.Get(); 16 | //for (int i = 0; i < 100; i++) 17 | //{ 18 | // var data = table.GetTable()[1].Ref as CsvDataRowRef; 19 | // new Building(_village, data, 1); 20 | //} 21 | 22 | //for (int i = 0; i < 100; i++) 23 | //{ 24 | // var data = table.GetTable()[1].Ref as CsvDataRowRef; 25 | // new Obstacle(_village, data); 26 | //} 27 | 28 | //for (int i = 0; i < 100; i++) 29 | //{ 30 | // var data = table.GetTable()[0].Ref as CsvDataRowRef; 31 | // new Trap(_village, data, 1); 32 | //} 33 | 34 | //for (int i = 0; i < 100; i++) 35 | //{ 36 | // var data = table.GetTable()[0].Ref as CsvDataRowRef; 37 | // new Decoration(_village, data); 38 | //} 39 | } 40 | 41 | private readonly Village _village; 42 | 43 | public override void Execute() 44 | { 45 | _village.ToJson(); 46 | } 47 | 48 | public override void TearDown() 49 | { 50 | _village.Dispose(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /benchmarks/Test/Village_ToJson2.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Data; 2 | using CoCSharp.Data.Models; 3 | using CoCSharp.Logic; 4 | 5 | namespace CoCSharp.Benchmark.Test 6 | { 7 | public class Village_ToJson2 : BenchmarkTest 8 | { 9 | public Village_ToJson2() 10 | { 11 | var manager = AssetManager.Default; 12 | _village = new Village(); 13 | 14 | //for (int i = 0; i < 395; i++) 15 | //{ 16 | // var data = manager.SearchCsv(1000000, 1); 17 | // new Building(_village, data); 18 | //} 19 | 20 | //for (int i = 0; i < 45; i++) 21 | //{ 22 | // var data = manager.SearchCsv(18000000, 0); 23 | // new Decoration(_village, data); 24 | //} 25 | } 26 | 27 | private readonly Village _village; 28 | 29 | public override void Execute() 30 | { 31 | _village.ToJson(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /scripts/csv_deomp.sh: -------------------------------------------------------------------------------- 1 | ( 2 | dd if=$1 bs=1 count=9 3 | dd if=/dev/zero bs=1 count=4 4 | dd if=$1 bs=1 skip=9 5 | ) | lzma -dc > 'decomp_'$1 6 | -------------------------------------------------------------------------------- /scripts/hexstr_to_csharparray.py: -------------------------------------------------------------------------------- 1 | # Converts a hex string into a valid C# byte array. 2 | 3 | import argparse 4 | 5 | def main(): 6 | parser = argparse.ArgumentParser(description='Converts a hex-string into a valid C# byte array.') 7 | parser.add_argument('hex', 8 | help='hex-string to convert') 9 | parser.add_argument('-n', '--name', 10 | help='variable name of the C# byte array') 11 | 12 | args = parser.parse_args() 13 | name = args.name 14 | hexstr = args.hex 15 | 16 | if name == None: 17 | name = 'array' 18 | 19 | final = 'var {0} = new byte[] {{ '.format(name) 20 | 21 | for i in range(0, len(hexstr), 2): 22 | value = hexstr[i:i + 2] 23 | final += '0x{0}'.format(value.upper()) 24 | 25 | if i != len(hexstr) - 2: 26 | final += ', ' 27 | 28 | final += ' };' 29 | 30 | print(final) 31 | 32 | if __name__ == "__main__": 33 | main(); 34 | -------------------------------------------------------------------------------- /src/CoCSharp.Client/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/CoCSharp.Client/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | namespace CoCSharp.Client 5 | { 6 | public static class Program 7 | { 8 | public static Client[] Clients { get; private set; } 9 | 10 | public static void Main(string[] args) 11 | { 12 | var endPoint = new IPEndPoint(IPAddress.Loopback, 9339); 13 | 14 | var client = new Client(); 15 | client.Connect(endPoint); 16 | client.Login(0, null); 17 | 18 | //const int NUM_CLIENT = 50; 19 | //Clients = new Client[NUM_CLIENT]; 20 | //for (int i = 0; i < NUM_CLIENT; i++) 21 | //{ 22 | // Clients[i] = new Client(); 23 | // Clients[i].Connect(endPoint); 24 | //} 25 | 26 | //for (int i = 0; i < NUM_CLIENT; i++) 27 | //{ 28 | // Clients[i].Login(0, null); 29 | //} 30 | 31 | //while (true) 32 | //{ 33 | // for (int i = 0; i < NUM_CLIENT; i++) 34 | // Clients[i].Tick(); 35 | 36 | // Thread.Sleep(16); 37 | //} 38 | Console.ReadLine(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/CoCSharp.Client/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CoCSharp.Client")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CoCSharp.Client")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("096633f8-1ee3-4f2f-ad44-978e4f247161")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/CoCSharp.Proxy/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/CoCSharp.Proxy/CommandMapper.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Logic; 2 | using CoCSharp.Network; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Reflection; 6 | 7 | namespace CoCSharp.Proxy 8 | { 9 | public class CommandMapper 10 | { 11 | public CommandMapper() 12 | { 13 | _cache = new Dictionary(); 14 | } 15 | 16 | private Dictionary _cache; 17 | 18 | public FieldMap[] Map(Command command) 19 | { 20 | var type = command.GetType(); 21 | return MapType(type); 22 | } 23 | 24 | private FieldMap[] MapType(Type type) 25 | { 26 | var map = default(FieldMap[]); 27 | // Look up if we've already cached this type. 28 | if (_cache.TryGetValue(type, out map)) 29 | return map; 30 | 31 | var fieldMaps = new List(); 32 | var fields = type.GetFields(); 33 | for (int i = 0; i < fields.Length; i++) 34 | { 35 | var fieldMap = MapField(fields[i]); 36 | fieldMaps.Add(fieldMap); 37 | } 38 | 39 | map = fieldMaps.ToArray(); 40 | // Register the map to cache. 41 | _cache.Add(type, map); 42 | 43 | return map; 44 | } 45 | 46 | private FieldMap MapField(FieldInfo field) 47 | { 48 | var fieldMap = new FieldMap(); 49 | fieldMap.Name = field.Name; 50 | fieldMap.Field = field; 51 | 52 | // Map fields with returning type which inherits from MessageComponent recursively. 53 | if (field.FieldType.BaseType == typeof(MessageComponent)) 54 | fieldMap.Child = MapType(field.FieldType); 55 | 56 | return fieldMap; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/CoCSharp.Proxy/MessageMapper.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Network; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Reflection; 5 | 6 | namespace CoCSharp.Proxy 7 | { 8 | public class MessageMapper 9 | { 10 | public MessageMapper() 11 | { 12 | _cache = new Dictionary(); 13 | } 14 | 15 | private Dictionary _cache; 16 | 17 | public FieldMap[] Map(Message message) 18 | { 19 | var type = message.GetType(); 20 | return MapType(type); 21 | } 22 | 23 | public FieldMap[] Map(MessageComponent component) 24 | { 25 | var type = component.GetType(); 26 | return MapType(type); 27 | } 28 | 29 | private FieldMap[] MapType(Type type) 30 | { 31 | var map = default(FieldMap[]); 32 | // Look up if we've already cached this type. 33 | if (_cache.TryGetValue(type, out map)) 34 | return map; 35 | 36 | var fieldMaps = new List(); 37 | var fields = type.GetFields(); 38 | for (int i = 0; i < fields.Length; i++) 39 | { 40 | var fieldMap = MapField(fields[i]); 41 | fieldMaps.Add(fieldMap); 42 | } 43 | 44 | map = fieldMaps.ToArray(); 45 | // Register the map to cache. 46 | _cache.Add(type, map); 47 | 48 | return map; 49 | } 50 | 51 | private FieldMap MapField(FieldInfo field) 52 | { 53 | var fieldMap = new FieldMap(); 54 | fieldMap.Name = field.Name; 55 | fieldMap.Field = field; 56 | 57 | // Map fields with returning type which inherits from MessageComponent recursively. 58 | if (field.FieldType.BaseType == typeof(MessageComponent)) 59 | fieldMap.Child = MapType(field.FieldType); 60 | 61 | return fieldMap; 62 | } 63 | } 64 | 65 | public class FieldMap 66 | { 67 | public FieldMap() 68 | { 69 | // Space 70 | } 71 | 72 | public string Name; 73 | public FieldInfo Field; 74 | public FieldMap[] Child; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/CoCSharp.Proxy/Program.cs: -------------------------------------------------------------------------------- 1 | using Ionic.Zip; 2 | using System; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Net; 6 | using System.Threading; 7 | 8 | namespace CoCSharp.Proxy 9 | { 10 | public class Program 11 | { 12 | public static Proxy Proxy { get; set; } 13 | 14 | public static void Main(string[] args) 15 | { 16 | Console.WriteLine("Compressing 'message-dumps' directory..."); 17 | CompressDir("message-dumps"); 18 | 19 | Console.WriteLine("Compressing 'village-dumps' directory..."); 20 | CompressDir("village-dumps"); 21 | 22 | var sw = Stopwatch.StartNew(); 23 | 24 | Proxy = new Proxy(); 25 | Proxy.Start(new IPEndPoint(IPAddress.Any, 9339)); 26 | 27 | sw.Stop(); 28 | 29 | Console.WriteLine("Done({0}ms)! Listening on *:9339", sw.Elapsed.TotalMilliseconds); 30 | Thread.Sleep(Timeout.Infinite); 31 | } 32 | 33 | private static void CompressDir(string path) 34 | { 35 | if (!Directory.Exists(path)) 36 | return; 37 | 38 | if (!Directory.Exists("compressed-dumps")) 39 | Directory.CreateDirectory("compressed-dumps"); 40 | 41 | var now = DateTime.Now; 42 | var fileName = Path.Combine("compressed-dumps", $"{path}_{now.ToString("yy_MM_dd_hh_mm_ss")}.zip"); 43 | using (var zip = new ZipFile(fileName)) 44 | { 45 | zip.AddDirectory(path); 46 | zip.Save(); 47 | } 48 | 49 | Directory.Delete(path, true); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/CoCSharp.Proxy/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CoCSharp.Proxy")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CoCSharp.Proxy")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("bd886993-1ee6-43de-ae44-147e0e1bf673")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/CoCSharp.Proxy/Proxy.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Network; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Net; 5 | using System.Net.Sockets; 6 | 7 | namespace CoCSharp.Proxy 8 | { 9 | public class Proxy 10 | { 11 | public Proxy() 12 | { 13 | Connections = new List(); 14 | Settings = new NetworkManagerAsyncSettings(); 15 | _listener = new Socket(SocketType.Stream, ProtocolType.Tcp); 16 | } 17 | 18 | public NetworkManagerAsyncSettings Settings { get; private set; } 19 | public List Connections { get; private set; } 20 | 21 | private Socket _listener; 22 | 23 | public void Start(IPEndPoint endPoint) 24 | { 25 | _listener.Bind(endPoint); 26 | _listener.Listen(10); 27 | _listener.BeginAccept(AcceptClient, _listener); 28 | } 29 | 30 | private void AcceptClient(IAsyncResult ar) 31 | { 32 | var client = _listener.EndAccept(ar); 33 | Console.WriteLine("Accepted new client: {0}", client.RemoteEndPoint); 34 | 35 | // Starts accepting as soon as possible. 36 | _listener.BeginAccept(AcceptClient, _listener); 37 | 38 | // Creates a new connection to the official server. 39 | var server = new Socket(SocketType.Stream, ProtocolType.Tcp); 40 | server.Connect("gamea.clashofclans.com", 9339); 41 | Console.WriteLine("Created new connection to gamea.clashofclans.com"); 42 | 43 | var connection = new Client(client, server, Settings); 44 | Connections.Add(connection); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/CoCSharp.Proxy/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Chatting/ChatCommand.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Server.Api.Chatting 2 | { 3 | /// 4 | /// Base class of a chat command. 5 | /// 6 | public abstract class ChatCommand : IChatCommand 7 | { 8 | /// 9 | /// Initializes a new instance of the class. 10 | /// 11 | public ChatCommand() 12 | { 13 | // Space 14 | } 15 | 16 | /// 17 | /// Gets the name of the 18 | /// 19 | public abstract string Name { get; } 20 | 21 | /// 22 | /// Gets the description of the . 23 | /// 24 | public virtual string Description => null; 25 | 26 | /// 27 | /// Gets the alias of the . 28 | /// 29 | public virtual string[] Alias => null; 30 | 31 | /// 32 | /// Gets or sets the that is handling this . 33 | /// 34 | public IChatManager Manager { get; set; } 35 | 36 | /// 37 | /// Executes the instance on the specified with the specified arguments. 38 | /// 39 | /// on which to execute this instance. 40 | /// Arguments to use. 41 | public abstract void Execute(IClient client, params string[] args); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Chatting/IChatCommand.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Server.Api.Chatting 2 | { 3 | /// 4 | /// Interface representing a chat command. 5 | /// 6 | public interface IChatCommand 7 | { 8 | /// 9 | /// Gets the name of the 10 | /// 11 | string Name { get; } 12 | 13 | /// 14 | /// Gets the alias of the . 15 | /// 16 | string[] Alias { get; } 17 | 18 | /// 19 | /// Gets the description of the . 20 | /// 21 | string Description { get; } 22 | 23 | /// 24 | /// Gets the that is handling this . 25 | /// 26 | IChatManager Manager { get; } 27 | 28 | /// 29 | /// Executes the instance on the specified with the specified arguments. 30 | /// 31 | /// on which to execute this instance. 32 | /// Arguments to use. 33 | void Execute(IClient client, params string[] args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Chatting/IChatManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace CoCSharp.Server.Api.Chatting 5 | { 6 | /// 7 | /// Interface representing a chat manager. 8 | /// 9 | public interface IChatManager 10 | { 11 | /// 12 | /// Handles the specified chat message. 13 | /// 14 | /// that sent the message. 15 | /// Chat message to handle. 16 | void Handle(IClient client, string message); 17 | 18 | /// 19 | /// Sends the specified chat message to the specified . 20 | /// 21 | /// to send the message to. 22 | /// Chat message to send. 23 | void SendChatMessage(IClient client, string message); 24 | 25 | /// 26 | /// Gets an that iterates through the available command types. 27 | /// 28 | /// An that iterates through the available command types. 29 | IEnumerable GetCommandTypes(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Core/Factories/ClanSaveFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CoCSharp.Server.Api.Db; 3 | using System.Threading; 4 | 5 | namespace CoCSharp.Server.Api.Core.Factories 6 | { 7 | /// 8 | /// Provides methods to create instances. 9 | /// 10 | public class ClanSaveFactory : IFactory 11 | { 12 | #region Constructors 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | public ClanSaveFactory() 17 | { 18 | // Space 19 | } 20 | #endregion 21 | 22 | #region Fields & Properties 23 | public IFactoryManager Manager { get; set; } 24 | 25 | private int _count; 26 | #endregion 27 | 28 | #region Methods 29 | public ClanSave Create() 30 | { 31 | Manager.Server.Logs.Info($"Created ClanSave {Interlocked.Increment(ref _count)} instances."); 32 | return new ClanSave(); 33 | } 34 | 35 | object IFactory.Create() 36 | { 37 | return Create(); 38 | } 39 | #endregion 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Core/Factories/LevelSaveFactory.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Server.Api.Db; 2 | using System.Threading; 3 | 4 | namespace CoCSharp.Server.Api.Core.Factories 5 | { 6 | /// 7 | /// Provides methods to create instances. 8 | /// 9 | public class LevelSaveFactory : IFactory 10 | { 11 | #region Constructors 12 | /// 13 | /// Initializes a new instance of the class. 14 | /// 15 | public LevelSaveFactory() 16 | { 17 | // Space 18 | } 19 | #endregion 20 | 21 | #region Fields & Properties 22 | /// 23 | /// Gets the which owns this . 24 | /// 25 | public IFactoryManager Manager { get; set; } 26 | 27 | private int _count; 28 | #endregion 29 | 30 | #region Methods 31 | public LevelSave Create() 32 | { 33 | Manager.Server.Logs.Info($"Created LevelSave {Interlocked.Increment(ref _count)} instances."); 34 | return new LevelSave(); 35 | } 36 | 37 | object IFactory.Create() 38 | { 39 | return Create(); 40 | } 41 | #endregion 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Core/ICacheManager.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Server.Api.Core 2 | { 3 | /// 4 | /// Interface representing a cache manager that caches object instances. 5 | /// 6 | public interface ICacheManager 7 | { 8 | bool TryGet(long id, out T obj); 9 | 10 | bool Register(long id, T obj); 11 | 12 | void Unregister(long id); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Core/IClanManager.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Logic; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace CoCSharp.Server.Api.Core 7 | { 8 | /// 9 | /// Interface representing a manager that manages instances. 10 | /// 11 | public interface IClanManager 12 | { 13 | IReadOnlyCollection Loaded { get; } 14 | 15 | Task GetClanAsync(long clanId, CancellationToken cancellationToken); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Core/IFactory.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Server.Api.Core 2 | { 3 | /// 4 | /// Interface representing a factory that produces objects. 5 | /// 6 | public interface IFactory 7 | { 8 | /// 9 | /// Gets or sets the which owns this . 10 | /// 11 | IFactoryManager Manager { get; set; } 12 | 13 | /// 14 | /// Returns an object produced by the . 15 | /// 16 | /// Object produced by the . 17 | object Create(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Core/IFactoryManager.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Server.Api.Core 2 | { 3 | /// 4 | /// Interface representing a factory manager that manages . 5 | /// 6 | public interface IFactoryManager 7 | { 8 | /// 9 | /// Gets the instance which owns this . 10 | /// 11 | IServer Server { get; } 12 | 13 | /// 14 | /// Returns an of the specified type registered to the . 15 | /// 16 | /// Type of to return. 17 | /// An of the specified type registered to the . 18 | TFactory GetFactory() where TFactory : IFactory, new(); 19 | 20 | /// 21 | /// Adds an of the specified type to the . 22 | /// 23 | /// Type of to add. 24 | void RegisterFactory() where TFactory : IFactory, new(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Core/IFactory{T}.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Server.Api.Core 2 | { 3 | /// 4 | /// Interface representing a factory that produces strongly typed objects. 5 | /// 6 | /// Type of object to produce. 7 | public interface IFactory : IFactory 8 | { 9 | /// 10 | /// Returns an object produced by the . 11 | /// 12 | /// Object produced by the . 13 | new T Create(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Core/ILevelManager.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Logic; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace CoCSharp.Server.Api.Core 7 | { 8 | /// 9 | /// Interface representing a manager that manages instances. 10 | /// 11 | public interface ILevelManager 12 | { 13 | IReadOnlyCollection Loaded { get; } 14 | 15 | Task GetLevelAsync(long userId, CancellationToken cancellationToken); 16 | 17 | Task NewLevelAsync(CancellationToken cancellationToken); 18 | 19 | Task NewLevelAsync(long userId, string userToken, CancellationToken cancellationToken); 20 | 21 | Task GetRandomLevelAsync(CancellationToken cancellationToken); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Core/IMessageHandler.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Network; 2 | using CoCSharp.Server.Api.Chatting; 3 | using System.Threading.Tasks; 4 | 5 | namespace CoCSharp.Server.Api.Core 6 | { 7 | /// 8 | /// Object that is going to handle incoming . 9 | /// 10 | public interface IMessageHandler 11 | { 12 | /// 13 | /// Gets the which owns the . 14 | /// 15 | IServer Server { get; } 16 | 17 | /// 18 | /// Gets the which is going to handle chat messages. 19 | /// 20 | IChatManager ChatManager { get; } 21 | 22 | /// 23 | /// Handles the specified asynchronously. 24 | /// 25 | /// that sent the message. 26 | /// that sent. 27 | /// 28 | Task HandleAsync(IClient client, Message message); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Db/ClanQuery.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Server.Api.Db 2 | { 3 | /// 4 | /// Represents a clan search. 5 | /// 6 | public struct ClanQuery 7 | { 8 | /// 9 | /// Search string. 10 | /// 11 | public string TextSearch; 12 | /// 13 | /// War frequency of clan. 14 | /// 15 | public int? WarFrequency; 16 | /// 17 | /// Location of clan. 18 | /// 19 | public int? ClanLocation; 20 | /// 21 | /// Minimum number of members. 22 | /// 23 | public int MinimumMembers; 24 | /// 25 | /// Maximum number of members. 26 | /// 27 | public int MaximumMembers; 28 | /// 29 | /// Trophy limit. 30 | /// 31 | public int PerkPoints; 32 | /// 33 | /// Whether to return clans that the user can't join as well. 34 | /// 35 | public bool OnlyCanJoin; 36 | /// 37 | /// Minimum level of the clan. 38 | /// 39 | public int ExpLevels; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Events/Server/ServerConnectionEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Server.Api.Events.Server 4 | { 5 | /// 6 | /// Event data for . 7 | /// 8 | public class ServerConnectionEventArgs : ServerEventArgs 9 | { 10 | enum ConnectionResult 11 | { 12 | Success, 13 | 14 | Failed, 15 | 16 | Banned 17 | }; 18 | 19 | #region Constructors 20 | /// 21 | /// Initializes a new instance of the class with 22 | /// the specified and . 23 | /// 24 | /// 25 | /// 26 | public ServerConnectionEventArgs(IServer server, IClient client) : base(server) 27 | { 28 | _client = client; 29 | } 30 | #endregion 31 | 32 | #region Fields & Properties 33 | private readonly IClient _client; 34 | 35 | /// 36 | /// Gets the which got connected. 37 | /// 38 | public IClient Client => _client; 39 | #endregion 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Events/Server/ServerEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Server.Api.Events.Server 4 | { 5 | /// 6 | /// Represents an raised by the server. 7 | /// 8 | public abstract class ServerEventArgs : EventArgs 9 | { 10 | #region Constructors 11 | /// 12 | /// Initializes a new instance of the class with 13 | /// the specified . 14 | /// 15 | /// 16 | public ServerEventArgs(IServer server) 17 | { 18 | if (server == null) 19 | throw new ArgumentNullException(nameof(server)); 20 | 21 | _server = server; 22 | } 23 | #endregion 24 | 25 | #region Fields & Properties 26 | private readonly IServer _server; 27 | 28 | /// 29 | /// Gets the which fired the event. 30 | /// 31 | public IServer Server => _server; 32 | #endregion 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/IClient.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Logic; 2 | using CoCSharp.Network; 3 | using CoCSharp.Server.Api.Db; 4 | using System; 5 | using System.Net; 6 | using System.Net.Sockets; 7 | 8 | namespace CoCSharp.Server.Api 9 | { 10 | /// 11 | /// Represents a remote client. 12 | /// 13 | public interface IClient : IDisposable 14 | { 15 | #region Fields & Properties 16 | /// 17 | /// Gets the which owns this . 18 | /// 19 | IServer Server { get; } 20 | 21 | /// 22 | /// Gets the to which the is connected to. 23 | /// 24 | Socket Connection { get; } 25 | 26 | /// 27 | /// Gets the local of the . 28 | /// 29 | EndPoint LocalEndPoint { get; } 30 | 31 | /// 32 | /// Gets the remote of the . 33 | /// 34 | EndPoint RemoteEndPoint { get; } 35 | 36 | /// 37 | /// Gets the associated with th e. 38 | /// 39 | Session Session { get; } 40 | 41 | /// 42 | /// Gets or sets the of when the last keep alive response was received. 43 | /// 44 | DateTime LastKeepAliveTime { get; set; } 45 | 46 | /// 47 | /// Gets or sets the of when the keep alive expires. 48 | /// 49 | DateTime KeepAliveExpireTime { get; set; } 50 | 51 | LevelSave Save { get; } 52 | #endregion 53 | 54 | #region Methods 55 | /// 56 | /// Sends the specified to the using the . 57 | /// 58 | /// to send. 59 | void SendMessage(Message message); 60 | #endregion 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Logging/ErrorLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Server.Api.Logging 4 | { 5 | /// 6 | /// Represents a logger that logs 'info' level logs. 7 | /// 8 | public class ErrorLogger : Logger 9 | { 10 | /// 11 | /// Gets the name of the . 12 | /// 13 | public override string Name => "error"; 14 | 15 | /// 16 | /// Method that is going to get called when gets called. 17 | /// 18 | /// Message to log. 19 | protected override string Write(object toLog) 20 | { 21 | return $"[{DateTime.UtcNow.ToString("yy/MM/dd - hh:mm:ss.fff")}][error] - {toLog}"; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Logging/InfoLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Server.Api.Logging 4 | { 5 | /// 6 | /// Represents a logger that logs 'info' level logs. 7 | /// 8 | public class InfoLogger : Logger 9 | { 10 | /// 11 | /// Gets the name of the . 12 | /// 13 | public override string Name => "info"; 14 | 15 | /// 16 | /// Method that is going to get called when gets called. 17 | /// 18 | /// Message to log. 19 | protected override string Write(object toLog) 20 | { 21 | return $"[{DateTime.UtcNow.ToString("yy/MM/dd - hh:mm:ss.fff")}][info] - {toLog}"; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Logging/WarnLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Server.Api.Logging 4 | { 5 | /// 6 | /// Represents a logger that logs 'info' level logs. 7 | /// 8 | public class WarnLogger : Logger 9 | { 10 | /// 11 | /// Gets the name of the . 12 | /// 13 | public override string Name => "warn"; 14 | 15 | /// 16 | /// Method that is going to get called when gets called. 17 | /// 18 | /// Message to log. 19 | protected override string Write(object toLog) 20 | { 21 | return $"[{DateTime.UtcNow.ToString("yy/MM/dd - hh:mm:ss.fff")}][warn] - {toLog}"; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/CoCSharp.Server.Api/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CoCSharp.Server.Api")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CoCSharp.Server.API")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("5b995462-1628-4fc1-b2f0-be7e0f8305a6")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/CoCSharp.Server/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/CoCSharp.Server/Chatting/Commands/ChangeLogChatCommand.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Server.Api; 2 | using CoCSharp.Server.Api.Chatting; 3 | using System.IO; 4 | 5 | namespace CoCSharp.Server.Chatting.Commands 6 | { 7 | public class ChangeLogChatCommand : ChatCommand 8 | { 9 | public override string Name => "changelog"; 10 | public override string Description => "Displays the change log."; 11 | 12 | private static string s_changeLog = "Change log: \n" + File.ReadAllText("contents/changelog"); 13 | 14 | public override void Execute(IClient client, params string[] args) 15 | { 16 | Manager.SendChatMessage(client, s_changeLog); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/CoCSharp.Server/Chatting/Commands/HelpChatCommand.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Server.Api; 2 | using CoCSharp.Server.Api.Chatting; 3 | using System; 4 | using System.Text; 5 | 6 | namespace CoCSharp.Server.Chatting.Commands 7 | { 8 | public class HelpChatCommand : ChatCommand 9 | { 10 | private static readonly string[] s_alias = new string[] { "h" }; 11 | 12 | public override string Name => "help"; 13 | public override string[] Alias => s_alias; 14 | public override string Description => "Displays this help message"; 15 | 16 | public override void Execute(IClient client, params string[] args) 17 | { 18 | var helpMessage = new StringBuilder(); 19 | helpMessage.AppendLine("List of available commands: "); 20 | 21 | foreach (var t in Manager.GetCommandTypes()) 22 | { 23 | var instance = (ChatCommand)Activator.CreateInstance(t); 24 | helpMessage.AppendFormat("/{0}", instance.Name); 25 | 26 | var alias = instance.Alias; 27 | if (alias != null && alias.Length > 0) 28 | { 29 | helpMessage.Append(","); 30 | for (int i = 0; i < instance.Alias.Length; i++) 31 | { 32 | var format = i == instance.Alias.Length - 1 ? "/{0}" : "/{0}"; 33 | helpMessage.AppendFormat(format, instance.Alias[i]); 34 | } 35 | helpMessage.AppendLine().AppendLine(" - " + instance.Description); 36 | } 37 | else 38 | { 39 | helpMessage.AppendLine(" - " + instance.Description); 40 | } 41 | 42 | helpMessage.AppendLine(); 43 | } 44 | 45 | Manager.SendChatMessage(client, helpMessage.ToString()); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/CoCSharp.Server/Chatting/Commands/StatisticsChatCommand.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Server.Api; 2 | using CoCSharp.Server.Api.Chatting; 3 | using System.Text; 4 | 5 | namespace CoCSharp.Server.Chatting.Commands 6 | { 7 | public class StatisticsChatCommand : ChatCommand 8 | { 9 | private static readonly string[] s_alias = new string[] { "stats" }; 10 | 11 | public override string Name => "statistics"; 12 | public override string[] Alias => s_alias; 13 | public override string Description => "Displays the statistics of the user that issued the command."; 14 | 15 | public override void Execute(IClient client, params string[] args) 16 | { 17 | var builder = new StringBuilder(); 18 | var level = client.Session.Level; 19 | var playTime = level.PlayTime; 20 | var loginCount = level.LoginCount; 21 | var dateJoined = level.DateCreated; 22 | var dateSaved = level.DateLastSave; 23 | 24 | builder.AppendLine($"Statistics for user {level.Avatar.Name}: "); 25 | builder.AppendLine($"Play time: {playTime.Hours}h {playTime.Minutes}m {playTime.Seconds}s"); 26 | builder.AppendLine($"Login count: {loginCount}"); 27 | builder.AppendLine($"Date joined: {dateJoined}"); 28 | builder.AppendLine($"Date saved: {dateSaved}"); 29 | Manager.SendChatMessage(client, builder.ToString()); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/CoCSharp.Server/Core/ClanManager.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Logic; 2 | using CoCSharp.Server.Api; 3 | using CoCSharp.Server.Api.Core; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace CoCSharp.Server.Core 10 | { 11 | public class ClanManager : IClanManager 12 | { 13 | public ClanManager(IServer server) 14 | { 15 | if (server == null) 16 | throw new ArgumentNullException(nameof(server)); 17 | 18 | _server = server; 19 | _loaded = new List(); 20 | } 21 | 22 | private readonly IServer _server; 23 | private readonly List _loaded; 24 | 25 | public IServer Server => _server; 26 | 27 | public IReadOnlyCollection Loaded => _loaded.AsReadOnly(); 28 | 29 | public async Task GetClanAsync(long clanId, CancellationToken cancellationToken) 30 | { 31 | if (_loaded.Count > 0) 32 | { 33 | for (int i = 0; i < _loaded.Count; i++) 34 | { 35 | cancellationToken.ThrowIfCancellationRequested(); 36 | 37 | var tmp = _loaded[i]; 38 | if (tmp.Id == clanId) 39 | return tmp; 40 | } 41 | } 42 | 43 | var save = await Server.Db.LoadClanAsync(clanId, cancellationToken); 44 | var clan = save.ToClan(); 45 | 46 | lock (_loaded) 47 | { 48 | _loaded.Add(clan); 49 | } 50 | 51 | return clan; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/CoCSharp.Server/Db/MySqlCommandExtensions.cs: -------------------------------------------------------------------------------- 1 | using MySql.Data.MySqlClient; 2 | using System.Data; 3 | 4 | namespace CoCSharp.Server.Db 5 | { 6 | internal static class MySqlCommandExtensions 7 | { 8 | public static void AddWithValue(this MySqlParameterCollection collection, string paramterName, object value) 9 | { 10 | var para = new MySqlParameter() 11 | { 12 | Value = value, 13 | ParameterName = paramterName 14 | }; 15 | 16 | var index = collection.Add(para); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/CoCSharp.Server/Db/MySqlTemplate.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Server.Db 2 | { 3 | // Methods to generate classes that can be retrieved from a MySql db. 4 | public class MySqlTemplate 5 | { 6 | //TODO: Implement. 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/CoCSharp.Server/Logging/ClanLogger.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Server.Api.Logging; 2 | using System; 3 | 4 | namespace CoCSharp.Server.Logging 5 | { 6 | public class ClanLogger : Logger 7 | { 8 | public override string Name => "clan"; 9 | 10 | protected override string Write(object toLog) 11 | { 12 | return $"[{DateTime.UtcNow.ToString("yy/MM/dd - hh:mm:ss.fff")}][clan] - {toLog}"; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/CoCSharp.Server/Logging/CleanErrorLogger.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Server.Api.Logging; 2 | using System; 3 | 4 | namespace CoCSharp.Server.Logging 5 | { 6 | public class CleanErrorLogger : Logger 7 | { 8 | public override string Name => "error-clean"; 9 | 10 | protected override string Write(object toLog) 11 | { 12 | return $"[{DateTime.UtcNow.ToString("yy/MM/dd - hh:mm:ss.fff")}][error-clean] - {toLog}"; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/CoCSharp.Server/Program.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Network.Cryptography; 2 | using CoCSharp.Network.Cryptography.NaCl.Internal; 3 | using CoCSharp.Server.Api; 4 | using System; 5 | using System.Diagnostics; 6 | using System.Threading; 7 | 8 | namespace CoCSharp.Server 9 | { 10 | public class Program 11 | { 12 | public static IServer Server { get; set; } 13 | 14 | public static void Main(string[] args) 15 | { 16 | Console.CancelKeyPress += (sender, e) => 17 | { 18 | if (!e.Cancel) 19 | { 20 | if (Server != null) 21 | { 22 | Server.Logs.Info("Closing server..."); 23 | Server.Close(); 24 | } 25 | } 26 | }; 27 | 28 | var sw = Stopwatch.StartNew(); 29 | 30 | Server = new Server(); 31 | Server.Logs.Info("Starting server..."); 32 | Server.ClientConnected += (sender, e) => 33 | { 34 | e.Server.Logs.Info($"New connection at {e.Client.RemoteEndPoint}"); 35 | }; 36 | 37 | Server.Start(); 38 | sw.Stop(); 39 | Server.Logs.Info($"Done in {sw.Elapsed.TotalMilliseconds}ms"); 40 | 41 | // Wasting the main thread, because we can. 42 | Thread.Sleep(Timeout.Infinite); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/CoCSharp.Server/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CoCSharp.Server")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CoCSharp.Server")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("542cada9-b065-4b67-b790-ab0b2eef46bd")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/CoCSharp.Server/RemoteSession.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CoCSharp.Logic; 3 | using CoCSharp.Server.Api; 4 | 5 | namespace CoCSharp.Server 6 | { 7 | public class RemoteSession : Session 8 | { 9 | #region Constructors 10 | public RemoteSession(IServer server) : base() 11 | { 12 | if (server == null) 13 | throw new ArgumentNullException(nameof(server)); 14 | 15 | _server = server; 16 | } 17 | #endregion 18 | 19 | #region Fields & Properties 20 | private readonly IServer _server; 21 | 22 | public IServer Server => _server; 23 | #endregion 24 | 25 | #region Methods 26 | public override Level SearchOpponent() 27 | { 28 | throw new NotImplementedException(); 29 | } 30 | #endregion 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/CoCSharp.Server/SocketAsyncEventArgsPool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net.Sockets; 4 | 5 | namespace CoCSharp.Server 6 | { 7 | internal sealed class SocketAsyncEventArgsPool : IDisposable 8 | { 9 | public SocketAsyncEventArgsPool(int capacity, EventHandler handler) 10 | { 11 | if (capacity < 1) 12 | throw new ArgumentOutOfRangeException("capacity cannot be less that 1."); 13 | 14 | Capacity = capacity; 15 | _handler = handler; 16 | _sync = new object(); 17 | _pool = new Stack(capacity); 18 | for (int i = 0; i < capacity; i++) 19 | { 20 | var args = CreateNew(); 21 | Push(args); 22 | } 23 | } 24 | 25 | private bool _disposed; 26 | private readonly object _sync; 27 | private readonly EventHandler _handler; 28 | private readonly Stack _pool; 29 | 30 | public int Capacity { get; private set; } 31 | public int Count { get { return _pool.Count; } } 32 | 33 | public SocketAsyncEventArgs CreateNew() 34 | { 35 | var args = new SocketAsyncEventArgs(); 36 | args.Completed += _handler; 37 | return args; 38 | } 39 | 40 | public SocketAsyncEventArgs Pop() 41 | { 42 | lock (_sync) 43 | { 44 | if (_pool.Count == 0) 45 | return null; 46 | 47 | return _pool.Pop(); 48 | } 49 | } 50 | 51 | public void Push(SocketAsyncEventArgs args) 52 | { 53 | lock (_sync) 54 | { 55 | _pool.Push(args); 56 | } 57 | } 58 | 59 | public void Dispose() 60 | { 61 | lock (_sync) 62 | { 63 | if (!_disposed) 64 | { 65 | for (int i = 0; i < _pool.Count; i++) 66 | { 67 | var args = _pool.Pop(); 68 | args.Dispose(); 69 | } 70 | _disposed = true; 71 | } 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/CoCSharp.Server/Utils.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Network; 2 | using System.Diagnostics; 3 | using System.IO; 4 | 5 | namespace CoCSharp.Server 6 | { 7 | public class Utils 8 | { 9 | public static T ReadMessageAt(string path) where T : Message, new() 10 | { 11 | var message = new T(); 12 | var file = File.ReadAllBytes(path); 13 | var stream = new MemoryStream(file); 14 | using (var reader = new MessageReader(stream)) 15 | { 16 | message.ReadMessage(reader); 17 | } 18 | 19 | return message; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/CoCSharp.Server/contents/changelog: -------------------------------------------------------------------------------- 1 | 1/6/2017: 2 | - Changed MySQL driver for true asynchronicity. 3 | - Messages that takes more than 4 seconds to process are canceled. 4 | 1/5/2017: 5 | - Improved memory management. 6 | - Minor MySQL table changes. 7 | 12/30/2016: 8 | - Fixed clan trophies calculations. 9 | 12/29/2016: 10 | - Added separate clan logs. 11 | - Reworked cache management. 12 | 12/28/2016: 13 | - Empty clans are now removed from the cache. 14 | - Fixed clan trophies calculations. 15 | - Time of when clan messages are sent are 16 | now tracked. 17 | - Added '/statistics' command. 18 | 12/27/2016: 19 | - Reworked logging system. 20 | 12/24/2016: 21 | - Fixed ExpPoints calculation issue. 22 | - Fixed frozen login screen issue. 23 | - Proper clan trophies calculations. 24 | - Proper clan member rankings. 25 | - Fixed .csv parsing issue which caused 26 | ExpPoints calculation issues. 27 | 12/22/2016: 28 | - Outdated client are now asked to download 29 | new updates. 30 | 12/21/2016: 31 | - Added welcome message. 32 | - Minor MySQL database modification. 33 | - Updated VisitHomeDataMessage 34 | to 8.709.2. 35 | 12/20/2016: 36 | - Changed protocol message receiving 37 | and processing order. 38 | - Updated AvatarProfileResponseMessage 39 | to 8.709.2. 40 | - Updated EnemyHomeDataMessage 41 | to 8.709.2. 42 | - Updated AllianceDataReponseMessage 43 | to 8.709.2. 44 | - Updated AllianceStreamMessage 45 | to 8.709.2. 46 | 12/19/2016: 47 | - Updated OwnHomeDataMessage 48 | to 8.709.2. 49 | 12/18/2016: 50 | - Added '/changelog' command. 51 | - Fixed potential issue with clan crashing client. 52 | 12/16/2016: 53 | - Reworked clan searching with filters. 54 | - Reworked clan MySQL management. 55 | - Improved cache management. 56 | 12/13/2016: 57 | - Moved the entire saving system to MySQL. 58 | 12/11/2016: 59 | - Added base of chat command handling. 60 | Use '/help' for more information. -------------------------------------------------------------------------------- /src/CoCSharp.Server/contents/welcome: -------------------------------------------------------------------------------- 1 | Happy new year 2017, hope you had a wonderful time! 2 | - With some love. -------------------------------------------------------------------------------- /src/CoCSharp.Server/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/CoCSharp/CoCSharp.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | ProjectFiles 5 | 6 | -------------------------------------------------------------------------------- /src/CoCSharp/Csv/Compression/Common/CRC.cs: -------------------------------------------------------------------------------- 1 | // Common/CRC.cs 2 | 3 | namespace SevenZip 4 | { 5 | class CRC 6 | { 7 | public static readonly uint[] Table; 8 | 9 | static CRC() 10 | { 11 | Table = new uint[256]; 12 | const uint kPoly = 0xEDB88320; 13 | for (uint i = 0; i < 256; i++) 14 | { 15 | uint r = i; 16 | for (int j = 0; j < 8; j++) 17 | if ((r & 1) != 0) 18 | r = (r >> 1) ^ kPoly; 19 | else 20 | r >>= 1; 21 | Table[i] = r; 22 | } 23 | } 24 | 25 | uint _value = 0xFFFFFFFF; 26 | 27 | public void Init() { _value = 0xFFFFFFFF; } 28 | 29 | public void UpdateByte(byte b) 30 | { 31 | _value = Table[(((byte)(_value)) ^ b)] ^ (_value >> 8); 32 | } 33 | 34 | public void Update(byte[] data, uint offset, uint size) 35 | { 36 | for (uint i = 0; i < size; i++) 37 | _value = Table[(((byte)(_value)) ^ data[offset + i])] ^ (_value >> 8); 38 | } 39 | 40 | public uint GetDigest() { return _value ^ 0xFFFFFFFF; } 41 | 42 | static uint CalculateDigest(byte[] data, uint offset, uint size) 43 | { 44 | CRC crc = new CRC(); 45 | // crc.Init(); 46 | crc.Update(data, offset, size); 47 | return crc.GetDigest(); 48 | } 49 | 50 | static bool VerifyDigest(uint digest, byte[] data, uint offset, uint size) 51 | { 52 | return (CalculateDigest(data, offset, size) == digest); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/CoCSharp/Csv/Compression/Common/InBuffer.cs: -------------------------------------------------------------------------------- 1 | // InBuffer.cs 2 | 3 | namespace SevenZip.Buffer 4 | { 5 | internal class InBuffer 6 | { 7 | byte[] m_Buffer; 8 | uint m_Pos; 9 | uint m_Limit; 10 | uint m_BufferSize; 11 | System.IO.Stream m_Stream; 12 | bool m_StreamWasExhausted; 13 | ulong m_ProcessedSize; 14 | 15 | public InBuffer(uint bufferSize) 16 | { 17 | m_Buffer = new byte[bufferSize]; 18 | m_BufferSize = bufferSize; 19 | } 20 | 21 | public void Init(System.IO.Stream stream) 22 | { 23 | m_Stream = stream; 24 | m_ProcessedSize = 0; 25 | m_Limit = 0; 26 | m_Pos = 0; 27 | m_StreamWasExhausted = false; 28 | } 29 | 30 | public bool ReadBlock() 31 | { 32 | if (m_StreamWasExhausted) 33 | return false; 34 | m_ProcessedSize += m_Pos; 35 | int aNumProcessedBytes = m_Stream.Read(m_Buffer, 0, (int)m_BufferSize); 36 | m_Pos = 0; 37 | m_Limit = (uint)aNumProcessedBytes; 38 | m_StreamWasExhausted = (aNumProcessedBytes == 0); 39 | return (!m_StreamWasExhausted); 40 | } 41 | 42 | 43 | public void ReleaseStream() 44 | { 45 | // m_Stream.Close(); 46 | m_Stream = null; 47 | } 48 | 49 | public bool ReadByte(byte b) // check it 50 | { 51 | if (m_Pos >= m_Limit) 52 | if (!ReadBlock()) 53 | return false; 54 | b = m_Buffer[m_Pos++]; 55 | return true; 56 | } 57 | 58 | public byte ReadByte() 59 | { 60 | // return (byte)m_Stream.ReadByte(); 61 | if (m_Pos >= m_Limit) 62 | if (!ReadBlock()) 63 | return 0xFF; 64 | return m_Buffer[m_Pos++]; 65 | } 66 | 67 | public ulong GetProcessedSize() 68 | { 69 | return m_ProcessedSize + m_Pos; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/CoCSharp/Csv/Compression/Common/OutBuffer.cs: -------------------------------------------------------------------------------- 1 | // OutBuffer.cs 2 | 3 | namespace SevenZip.Buffer 4 | { 5 | internal class OutBuffer 6 | { 7 | byte[] m_Buffer; 8 | uint m_Pos; 9 | uint m_BufferSize; 10 | System.IO.Stream m_Stream; 11 | ulong m_ProcessedSize; 12 | 13 | public OutBuffer(uint bufferSize) 14 | { 15 | m_Buffer = new byte[bufferSize]; 16 | m_BufferSize = bufferSize; 17 | } 18 | 19 | public void SetStream(System.IO.Stream stream) { m_Stream = stream; } 20 | public void FlushStream() { m_Stream.Flush(); } 21 | public void CloseStream() { m_Stream.Close(); } 22 | public void ReleaseStream() { m_Stream = null; } 23 | 24 | public void Init() 25 | { 26 | m_ProcessedSize = 0; 27 | m_Pos = 0; 28 | } 29 | 30 | public void WriteByte(byte b) 31 | { 32 | m_Buffer[m_Pos++] = b; 33 | if (m_Pos >= m_BufferSize) 34 | FlushData(); 35 | } 36 | 37 | public void FlushData() 38 | { 39 | if (m_Pos == 0) 40 | return; 41 | m_Stream.Write(m_Buffer, 0, (int)m_Pos); 42 | m_Pos = 0; 43 | } 44 | 45 | public ulong GetProcessedSize() { return m_ProcessedSize + m_Pos; } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/CoCSharp/Csv/Compression/Compress/LZ/IMatchFinder.cs: -------------------------------------------------------------------------------- 1 | // IMatchFinder.cs 2 | 3 | using System; 4 | 5 | namespace SevenZip.Compression.LZ 6 | { 7 | interface IInWindowStream 8 | { 9 | void SetStream(System.IO.Stream inStream); 10 | void Init(); 11 | void ReleaseStream(); 12 | Byte GetIndexByte(Int32 index); 13 | UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit); 14 | UInt32 GetNumAvailableBytes(); 15 | } 16 | 17 | interface IMatchFinder : IInWindowStream 18 | { 19 | void Create(UInt32 historySize, UInt32 keepAddBufferBefore, 20 | UInt32 matchMaxLen, UInt32 keepAddBufferAfter); 21 | UInt32 GetMatches(UInt32[] distances); 22 | void Skip(UInt32 num); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/CoCSharp/Csv/Compression/README.txt: -------------------------------------------------------------------------------- 1 | All code in the CoCSharp/Csv/Compression directory except LzmaUtils.cs was taken directly from 2 | the LZMA SDK available at: 3 | 4 | http://www.7-zip.org/sdk.html 5 | -------------------------------------------------------------------------------- /src/CoCSharp/Csv/CsvAliasAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Csv 4 | { 5 | /// 6 | /// Instruct the to serialize a property with the specified 7 | /// alias name. 8 | /// 9 | [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] 10 | public sealed class CsvAliasAttribute : Attribute 11 | { 12 | /// 13 | /// Initializes a new instance of the class with 14 | /// the specified alias name. 15 | /// 16 | /// The alias name of the field. 17 | public CsvAliasAttribute(string alias) 18 | { 19 | Alias = alias; 20 | } 21 | 22 | /// 23 | /// Gets or sets alias name. 24 | /// 25 | public string Alias { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/CoCSharp/Csv/CsvAttributeHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace CoCSharp.Csv 5 | { 6 | internal static class CsvAttributeHelper 7 | { 8 | static CsvAttributeHelper() 9 | { 10 | s_csvAliasType = typeof(CsvAliasAttribute); 11 | s_csvIgnoreType = typeof(CsvIgnoreAttribute); 12 | } 13 | 14 | private static readonly Type s_csvAliasType; 15 | private static readonly Type s_csvIgnoreType; 16 | 17 | public static string GetPropertyAlias(PropertyInfo property) 18 | { 19 | var attributes = (CsvAliasAttribute[])property.GetCustomAttributes(s_csvAliasType, true); 20 | if (attributes.Length == 0) 21 | return property.Name; 22 | return attributes[0].Alias; 23 | } 24 | 25 | public static bool IsIgnored(PropertyInfo property) 26 | { 27 | return property.GetCustomAttribute(s_csvIgnoreType) != null; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/CoCSharp/Csv/CsvDataColumn.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Csv 2 | { 3 | /// 4 | /// Represents a column in a . 5 | /// 6 | public class CsvDataColumn 7 | { 8 | #region Constructors 9 | /// 10 | /// Initializes a new instance of the class. 11 | /// 12 | public CsvDataColumn() 13 | { 14 | _dataLevel = -1; 15 | } 16 | #endregion 17 | 18 | #region Fields & Properties 19 | internal int _dataLevel; 20 | internal CsvDataTable _table; 21 | 22 | /// 23 | /// Gets the which contains this . 24 | /// 25 | public CsvDataTable Table => _table; 26 | 27 | /// 28 | /// Gets the level of the data stored by the . 29 | /// 30 | public int DataLevel => _dataLevel; 31 | #endregion 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/CoCSharp/Csv/CsvDataTable{T}.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Csv 2 | { 3 | /// 4 | /// Represents a strongly typed table of of the specified type, . 5 | /// 6 | /// Type of to store. 7 | public class CsvDataTable : CsvDataTable where TCsvData : CsvData, new() 8 | { 9 | #region Constructors 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | public CsvDataTable() : base(typeof(TCsvData)) 14 | { 15 | _rows = (CsvDataRowCollection)base.Rows; 16 | } 17 | #endregion 18 | 19 | #region Fields & Properties 20 | private readonly CsvDataRowCollection _rows; 21 | 22 | /// 23 | /// Gets the associated with this . 24 | /// 25 | public new CsvDataRowCollection Rows => _rows; 26 | #endregion 27 | 28 | #region Methods 29 | #endregion 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/CoCSharp/Csv/CsvException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Csv 4 | { 5 | /// 6 | /// The exception thrown when an error occurs during CSV serialization or deserialization. 7 | /// 8 | public class CsvException : Exception 9 | { 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | public CsvException() 14 | : base() 15 | { 16 | // Space 17 | } 18 | 19 | /// 20 | /// Initializes a new instance of the class with 21 | /// the specified error message. 22 | /// 23 | /// Message of the . 24 | public CsvException(string message) 25 | : base(message) 26 | { 27 | // Space 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/CoCSharp/Csv/CsvIgnoreAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Csv 4 | { 5 | /// 6 | /// Instructs the to not serialize the member. This class cannot be inherited. 7 | /// 8 | [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] 9 | public sealed class CsvIgnoreAttribute : Attribute 10 | { 11 | /// 12 | /// Initializes a new instance of the class. 13 | /// 14 | public CsvIgnoreAttribute() 15 | { 16 | // Space 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/CoCSharp/Csv/CsvTableCompression.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Csv 2 | { 3 | /// 4 | /// Defines the type of compression of .csv files. 5 | /// 6 | public enum CsvTableCompression 7 | { 8 | /// 9 | /// Table is Compressed. 10 | /// 11 | Compressed = 0, 12 | 13 | /// 14 | /// Table is uncompressed. 15 | /// 16 | Uncompressed = 1, 17 | 18 | /// 19 | /// Use auto detection of compression. Auto detection of compression is not guaranteed to work. 20 | /// 21 | Auto = 2 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/CoCSharp/Csv/ObjectMapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | 5 | namespace CoCSharp.Csv 6 | { 7 | internal class ObjectMapper 8 | { 9 | private const string NameColumn = "Name"; 10 | 11 | public ObjectMapper() 12 | { 13 | // Space 14 | } 15 | 16 | public PropertyMap[] MapProperties(Type type, CsvTable table) 17 | { 18 | if (type == null) 19 | throw new ArgumentNullException("type"); 20 | 21 | var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); 22 | var propertyMaps = new List(); 23 | for (int i = 0; i < properties.Length; i++) 24 | { 25 | var property = properties[i]; 26 | // If we need to ignore it, don't add the property to the map. 27 | if (CsvAttributeHelper.IsIgnored(property)) 28 | continue; 29 | // If it does not have a setter, we ignore it. 30 | var setter = property.GetSetMethod(true); 31 | if (setter == null) 32 | continue; 33 | // If it does not have a getter, we ignore it. 34 | var getter = property.GetGetMethod(true); 35 | if (getter == null) 36 | continue; 37 | 38 | var map = new PropertyMap(); 39 | var name = CsvAttributeHelper.GetPropertyAlias(property); 40 | var index = table.Columns.IndexOf(name); 41 | if (index == -1) 42 | continue; 43 | 44 | map.Name = name; 45 | map.ColumnIndex = index; 46 | map.PropertyName = property.Name; 47 | map.PropertyType = property.PropertyType; 48 | map.Getter = getter; 49 | map.Setter = setter; 50 | map.DeclaringType = property.DeclaringType; 51 | 52 | // Make sure TID property is first. 53 | if (map.Name == NameColumn) 54 | propertyMaps.Insert(0, map); 55 | else 56 | propertyMaps.Add(map); 57 | } 58 | return propertyMaps.ToArray(); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/CoCSharp/Csv/PropertyMap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data; 3 | using System.Reflection; 4 | 5 | namespace CoCSharp.Csv 6 | { 7 | internal struct PropertyMap 8 | { 9 | public string Name; 10 | 11 | public DataColumn Column; 12 | 13 | public int ColumnIndex; 14 | 15 | public string PropertyName; 16 | 17 | public Type PropertyType; 18 | 19 | public MethodInfo Getter; 20 | 21 | public MethodInfo Setter; 22 | 23 | public Type DeclaringType; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/CoCSharp/Data/AssetDownloadCompletedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Data 4 | { 5 | /// 6 | /// Provides data for event. 7 | /// 8 | public class AssetDownloadCompletedEventArgs : EventArgs 9 | { 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | public AssetDownloadCompletedEventArgs() 14 | { 15 | // Space 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/CoCSharp/Data/AssetDownloadProgressChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Data 4 | { 5 | /// 6 | /// Provides data for event. 7 | /// 8 | public class AssetDownloadProgressChangedEventArgs : EventArgs 9 | { 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | public AssetDownloadProgressChangedEventArgs() 14 | { 15 | // Space 16 | } 17 | 18 | /// 19 | /// Gets or sets the downloaded. 20 | /// 21 | public FingerprintFile FileDownloaded { get; set; } 22 | 23 | /// 24 | /// Gets or sets the next to download. 25 | /// 26 | public FingerprintFile NextDownload { get; set; } 27 | 28 | /// 29 | /// Gets or sets the percentage progress made based on downloaded count per total downloads. 30 | /// 31 | public double ProgressPercentage { get; set; } 32 | 33 | /// 34 | /// Gets or sets the amount of files downloaded. 35 | /// 36 | public int DownloadedCount { get; set; } 37 | 38 | /// 39 | /// Gets or sets a value indicating whether the file was downloaded. 40 | /// 41 | public bool WasDownloaded { get; set; } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/CoCSharp/Data/AssetProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Data 4 | { 5 | // Base AssetProvider class. Used to load assets and get/return them. 6 | internal abstract class AssetProvider : IDisposable 7 | { 8 | private bool _disposed; 9 | 10 | // Loads the asset for the specified type, at the specified path. 11 | public abstract void LoadAsset(Type type, string path); 12 | 13 | // Unloads the asset for the specified type. 14 | public abstract bool UnloadAsset(Type type); 15 | 16 | // Returns a loaded asset for the specified type. 17 | public abstract object GetAsset(Type type); 18 | 19 | public void Dispose() 20 | { 21 | Dispose(true); 22 | } 23 | 24 | protected virtual void Dispose(bool disposing) 25 | { 26 | if (_disposed) 27 | return; 28 | 29 | // Not much. 30 | _disposed = true; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/CoCSharp/Data/FingerprintFile.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Data 2 | { 3 | /// 4 | /// Represents a file's fingerprint in a . 5 | /// 6 | public class FingerprintFile 7 | { 8 | /// 9 | /// Initializes a new instance of the class. 10 | /// 11 | public FingerprintFile() 12 | { 13 | // Space 14 | } 15 | 16 | /// 17 | /// Gets or sets the SHA-1 hash of the file. 18 | /// 19 | public string Hash { get; set; } 20 | 21 | /// 22 | /// Gets or sets the path of the file. 23 | /// 24 | public string Path { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/CoCSharp/Data/Models/ExperienceLevelData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CoCSharp.Csv; 3 | 4 | namespace CoCSharp.Data.Models 5 | { 6 | /// 7 | /// Defines data from the logic/experience_levels.csv file. 8 | /// 9 | public class ExperienceLevelData : CsvData 10 | { 11 | /// 12 | /// Initializes a new instance of the class. 13 | /// 14 | public ExperienceLevelData() 15 | { 16 | // Space 17 | } 18 | 19 | internal override int KindId => 11; 20 | 21 | // NOTE: This was generated from the experience_levels.csv using gen_csv_properties.py script. 22 | 23 | /// 24 | /// Gets or sets Name. 25 | /// 26 | public string Name { get; set; } 27 | /// 28 | /// Gets or sets Exp points. 29 | /// 30 | public int ExpPoints { get; set; } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/CoCSharp/Data/Models/GlobalData.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Csv; 2 | 3 | namespace CoCSharp.Data.Models 4 | { 5 | /// 6 | /// Defines data from the logic/globals.csv file. 7 | /// 8 | public class GlobalData : CsvData 9 | { 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | public GlobalData() 14 | { 15 | // Space 16 | } 17 | 18 | // NOTE: This was generated from the globals.csv using gen_csv_properties.py script. 19 | internal override int KindId => 14; 20 | 21 | /// 22 | /// Gets or sets the Name of the global. 23 | /// 24 | public string Name { get; set; } 25 | /// 26 | /// Gets or sets Number value. 27 | /// 28 | public int NumberValue { get; set; } 29 | /// 30 | /// Gets or sets Boolean value. 31 | /// 32 | public bool BooleanValue { get; set; } 33 | /// 34 | /// Gets or sets Text value. 35 | /// 36 | public string TextValue { get; set; } 37 | /// 38 | /// Gets or sets Number array. 39 | /// 40 | public int NumberArray { get; set; } 41 | /// 42 | /// Gets or sets Alt number array. 43 | /// 44 | public int AltNumberArray { get; set; } 45 | /// 46 | /// Gets or sets String array. 47 | /// 48 | public string StringArray { get; set; } 49 | /// 50 | /// Gets or sets Alt string array. 51 | /// 52 | public string AltStringArray { get; set; } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/CoCSharp/Data/Slots/AchievementSlot.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Network; 2 | using System; 3 | using System.Diagnostics; 4 | 5 | namespace CoCSharp.Data.Slots 6 | { 7 | /// 8 | /// Represents a Clash of Clans achievement slot. 9 | /// 10 | [DebuggerDisplay("ID = {ID}")] 11 | public class AchievementSlot : Slot 12 | { 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | public AchievementSlot() 17 | { 18 | // Space 19 | } 20 | 21 | /// 22 | /// Initializes a new instance of the class with 23 | /// the specified achievement ID. 24 | /// 25 | /// ID of the achievement. 26 | public AchievementSlot(int id) 27 | { 28 | Id = id; 29 | } 30 | 31 | /// 32 | /// Reads the from the specified . 33 | /// 34 | /// 35 | /// that will be used to read the . 36 | /// 37 | /// is null. 38 | public override void ReadSlot(MessageReader reader) 39 | { 40 | ThrowIfReaderNull(reader); 41 | 42 | Id = reader.ReadInt32(); 43 | } 44 | 45 | /// 46 | /// Writes the to the specified . 47 | /// 48 | /// 49 | /// that will be used to write the . 50 | /// 51 | /// is null. 52 | public override void WriteSlot(MessageWriter writer) 53 | { 54 | ThrowIfWriterNull(writer); 55 | 56 | writer.Write(Id); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/CoCSharp/Data/Slots/TutorialProgressSlot.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Network; 2 | using System; 3 | using System.Diagnostics; 4 | 5 | namespace CoCSharp.Data.Slots 6 | { 7 | /// 8 | /// Represents a Clash of Clans tutorial(mission) progress slot. 9 | /// 10 | [DebuggerDisplay("ID = {ID}")] 11 | public class TutorialProgressSlot : Slot 12 | { 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | public TutorialProgressSlot() 17 | { 18 | // Space 19 | } 20 | 21 | /// 22 | /// Initializes a new instance of the class with 23 | /// the specified mission ID. 24 | /// 25 | /// ID of the mission. 26 | public TutorialProgressSlot(int id) 27 | { 28 | Id = id; 29 | } 30 | 31 | /// 32 | /// Reads the from the specified . 33 | /// 34 | /// 35 | /// that will be used to read the . 36 | /// 37 | /// is null. 38 | public override void ReadSlot(MessageReader reader) 39 | { 40 | ThrowIfReaderNull(reader); 41 | 42 | Id = reader.ReadInt32(); 43 | } 44 | 45 | /// 46 | /// Writes the to the specified . 47 | /// 48 | /// 49 | /// that will be used to write the . 50 | /// 51 | /// is null. 52 | public override void WriteSlot(MessageWriter writer) 53 | { 54 | ThrowIfWriterNull(writer); 55 | 56 | writer.Write(Id); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/CoCSharp/Data/Slots/UnknownSlot.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Network; 2 | using System; 3 | using System.Diagnostics; 4 | 5 | namespace CoCSharp.Data.Slots 6 | { 7 | /// 8 | /// Represents an unknown slot. 9 | /// 10 | [DebuggerDisplay("ID = {Id}, Value = {Value}")] 11 | public class UnknownSlot : Slot 12 | { 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | public UnknownSlot() 17 | { 18 | // Space 19 | } 20 | 21 | /// 22 | /// Gets or sets the value of the unknown slot. 23 | /// 24 | public int Value { get; set; } 25 | 26 | /// 27 | /// Reads the from the specified . 28 | /// 29 | /// 30 | /// that will be used to read the . 31 | /// 32 | /// is null. 33 | public override void ReadSlot(MessageReader reader) 34 | { 35 | ThrowIfReaderNull(reader); 36 | 37 | Id = reader.ReadInt32(); 38 | Value = reader.ReadInt32(); 39 | } 40 | 41 | /// 42 | /// Writes the to the specified . 43 | /// 44 | /// 45 | /// that will be used to write the . 46 | /// 47 | /// is null. 48 | public override void WriteSlot(MessageWriter writer) 49 | { 50 | ThrowIfWriterNull(writer); 51 | 52 | writer.Write(Id); 53 | writer.Write(Value); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/CoCSharp/Data/Slot{T}.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Csv; 2 | 3 | namespace CoCSharp.Data 4 | { 5 | /// 6 | /// Represents a Clash of Clans slot which is strongly associated to a and 7 | /// refers to it. 8 | /// 9 | /// 10 | /// 11 | /// to which the is associated with. 12 | /// 13 | public abstract class Slot : Slot where TCsvData : CsvData, new() 14 | { 15 | /// 16 | /// Initializes a new instance of the class. 17 | /// 18 | protected Slot() 19 | { 20 | _instance = CsvData.GetInstance(); 21 | } 22 | 23 | private readonly TCsvData _instance; 24 | 25 | internal override bool InvalidDataId(int dataId) 26 | { 27 | return _instance.InvalidDataID(dataId); 28 | } 29 | 30 | internal override string GetArgsOutOfRangeMessage(string paramName) 31 | { 32 | return _instance.GetArgsOutOfRangeMessage(paramName); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/CoCSharp/InternalConstants.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp 2 | { 3 | internal static class InternalConstants 4 | { 5 | public const int IdBase = 1000000; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/CoCSharp/Logic/ClanMemberRole.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Logic 2 | { 3 | /// 4 | /// Defines clan member roles. 5 | /// 6 | public enum ClanMemberRole : int 7 | { 8 | /// 9 | /// A member of the clan. 10 | /// 11 | Member = 1, 12 | 13 | /// 14 | /// Leader of the clan. 15 | /// 16 | Leader = 2, 17 | 18 | /// 19 | /// An elder of the clan. 20 | /// 21 | Elder = 3, 22 | 23 | /// 24 | /// A co-leader of the clan. 25 | /// 26 | CoLeader = 4 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /src/CoCSharp/Logic/ClearingFinishedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Logic 4 | { 5 | /// 6 | /// Provides arguments data for clearing finish event. 7 | /// 8 | public class ClearingFinishedEventArgs : EventArgs 9 | { 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | public ClearingFinishedEventArgs() 14 | { 15 | // Space 16 | } 17 | 18 | /// 19 | /// Gets or sets the that was cleared. 20 | /// 21 | public Obstacle ClearedObstacle { get; set; } 22 | 23 | private DateTime _endTime; 24 | /// 25 | /// Gets or sets the UTC time at which the obstacle clearing operation was finished. 26 | /// 27 | public DateTime EndTime 28 | { 29 | get 30 | { 31 | return _endTime; 32 | } 33 | set 34 | { 35 | if (value.Kind != DateTimeKind.Utc) 36 | throw new ArgumentException("EndTime.Kind must be in DateTimeKind.Utc.", "value"); 37 | 38 | _endTime = value; 39 | } 40 | } 41 | 42 | /// 43 | /// Gets or sets whether the clearing of the was cancelled, 44 | /// that is when is called. 45 | /// 46 | public bool WasCancelled { get; set; } 47 | 48 | /// 49 | /// Gets or sets the user token object associated with the that was 50 | /// cleared. 51 | /// 52 | public object UserToken { get; set; } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/CoCSharp/Logic/CommandFactorySuppressAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Logic 4 | { 5 | /// 6 | /// Use this attribute to prevent the to add it 7 | /// in the . This class cannot be inherited. 8 | /// 9 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] 10 | internal sealed class CommandFactorySuppressAttribute : Attribute 11 | { 12 | public CommandFactorySuppressAttribute(bool suppress = true) 13 | { 14 | Suppress = suppress; 15 | } 16 | 17 | public bool Suppress { get; private set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/CoCSharp/Logic/Commands/CastSpellCommand.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Network; 2 | 3 | namespace CoCSharp.Logic.Commands 4 | { 5 | public class CastSpellCommand : Command 6 | { 7 | /// 8 | /// Initializes a new instance of the class. 9 | /// 10 | public CastSpellCommand() 11 | { 12 | // Space 13 | } 14 | 15 | public override int Id => 604; 16 | 17 | public int X; 18 | public int Y; 19 | public int SpellDataID; 20 | 21 | public override void ReadCommand(MessageReader reader) 22 | { 23 | ThrowIfReaderNull(reader); 24 | 25 | X = reader.ReadInt32(); 26 | Y = reader.ReadInt32(); 27 | SpellDataID = reader.ReadInt32(); 28 | Tick = reader.ReadInt32(); 29 | } 30 | 31 | public override void WriteCommand(MessageWriter writer) 32 | { 33 | ThrowIfWriterNull(writer); 34 | 35 | writer.Write(X); 36 | writer.Write(Y); 37 | writer.Write(SpellDataID); 38 | writer.Write(Tick); 39 | } 40 | 41 | public override void Execute(Level level) 42 | { 43 | ThrowIfLevelNull(level); 44 | 45 | //TODO: Implement TickTiming and stuff. 46 | var slot = level.Avatar.Spells.GetSlot(SpellDataID); 47 | if (slot != null) 48 | slot.Amount--; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/CoCSharp/Logic/Commands/PlaceAttackerCommand.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Network; 2 | using System.Diagnostics; 3 | 4 | namespace CoCSharp.Logic.Commands 5 | { 6 | public class PlaceAttackerCommand : Command 7 | { 8 | /// 9 | /// Initializes a new instance of the class. 10 | /// 11 | public PlaceAttackerCommand() 12 | { 13 | // Space 14 | } 15 | 16 | public override int Id => 600; 17 | 18 | public int X; 19 | public int Y; 20 | public int UnitDataId; 21 | 22 | public override void ReadCommand(MessageReader reader) 23 | { 24 | ThrowIfReaderNull(reader); 25 | 26 | X = reader.ReadInt32(); 27 | Y = reader.ReadInt32(); 28 | UnitDataId = reader.ReadInt32(); 29 | Tick = reader.ReadInt32(); 30 | 31 | //var nx = (X >> 8) / 2; 32 | //var ny = (Y >> 8) / 2; 33 | } 34 | 35 | public override void WriteCommand(MessageWriter writer) 36 | { 37 | ThrowIfWriterNull(writer); 38 | 39 | writer.Write(X); 40 | writer.Write(Y); 41 | writer.Write(UnitDataId); 42 | writer.Write(Tick); 43 | } 44 | 45 | public override void Execute(Level level) 46 | { 47 | ThrowIfLevelNull(level); 48 | 49 | Debug.Assert(level.State >= 1, "Command was executed when the level was in an incorrect state."); 50 | 51 | // State == 2, means we're attacking the player. 52 | level.State = 2; 53 | 54 | // Look the UnitSlot in the avatar's UnitSlotCollection and 55 | // decrement its amount. 56 | var slot = level.Avatar.Units.GetSlot(UnitDataId); 57 | if (slot != null) 58 | slot.Amount--; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/CoCSharp/Logic/ComponentPool.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | 3 | namespace CoCSharp.Logic 4 | { 5 | internal static class ComponentPool 6 | { 7 | private const int PoolArraySize = 8; 8 | 9 | static ComponentPool() 10 | { 11 | _pools = new ConcurrentBag[PoolArraySize]; 12 | for (int i = 0; i < _pools.Length; i++) 13 | _pools[i] = new ConcurrentBag(); 14 | } 15 | 16 | public static int TotalCount 17 | { 18 | get 19 | { 20 | var sum = 0; 21 | for (int i = 0; i < PoolArraySize; i++) 22 | sum += _pools[i].Count; 23 | return sum; 24 | } 25 | } 26 | 27 | private static readonly ConcurrentBag[] _pools; 28 | 29 | public static void Push(Component component) 30 | { 31 | if (component == null) 32 | return; 33 | 34 | GetPool(component.ComponentID).Add(component); 35 | } 36 | 37 | public static bool TryPop(int componentId, out Component component) 38 | { 39 | return GetPool(componentId).TryTake(out component); 40 | } 41 | 42 | public static int GetCount(int componentId) 43 | { 44 | return GetPool(componentId).Count; 45 | } 46 | 47 | public static ConcurrentBag GetPool(int componentId) 48 | { 49 | return _pools[componentId]; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/CoCSharp/Logic/LevelLog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.IO; 4 | 5 | namespace CoCSharp.Logic 6 | { 7 | /// 8 | /// Provides methods to log information about a . 9 | /// 10 | public class LevelLog 11 | { 12 | #region Constructors 13 | /// 14 | /// Initializes a new instance of the class with the specified 15 | /// . 16 | /// 17 | /// which is associated with this . 18 | protected internal LevelLog(Level level) 19 | { 20 | if (level == null) 21 | throw new ArgumentNullException(nameof(level)); 22 | 23 | _level = level; 24 | _fileName = _level.Token + "-level.log"; 25 | _sync = new object(); 26 | } 27 | #endregion 28 | 29 | #region Fields & Properties 30 | /// 31 | /// Gets the associated with the . 32 | /// 33 | protected Level Level => _level; 34 | 35 | private readonly object _sync; 36 | private readonly string _fileName; 37 | private readonly Level _level; 38 | #endregion 39 | 40 | #region Methods 41 | /// 42 | /// Logs the specified message to the . 43 | /// 44 | /// Message to log. 45 | public void Log(string message) 46 | { 47 | #if DEBUG 48 | lock (_sync) 49 | { 50 | var file = File.Open(_fileName, FileMode.Append); 51 | using (var writer = new StreamWriter(file)) 52 | writer.WriteLine(message); 53 | 54 | Debug.WriteLine(message); 55 | } 56 | #endif 57 | } 58 | #endregion 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/CoCSharp/Logic/SessionState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Logic 4 | { 5 | /// 6 | /// Defines value indicating the state of a . 7 | /// 8 | [Flags] 9 | public enum SessionState 10 | { 11 | /// 12 | /// is in its default state. 13 | /// 14 | None = 0, 15 | 16 | /// 17 | /// is logged in with a . 18 | /// 19 | LoggedIn = 1, 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/CoCSharp/Logic/VillageObjectPool.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | 3 | namespace CoCSharp.Logic 4 | { 5 | // An array of pools each representing an object type. 6 | // VillageObject.PushToPool will push the VillageObject here. 7 | internal static class VillageObjectPool 8 | { 9 | private const int PoolArraySize = 8; 10 | 11 | static VillageObjectPool() 12 | { 13 | // Initialize a pool array of 8 element, each representing a VillageObject type. 14 | _pools = new ConcurrentBag[PoolArraySize]; 15 | for (int i = 0; i < PoolArraySize; i++) 16 | _pools[i] = new ConcurrentBag(); 17 | } 18 | 19 | public static int TotalCount 20 | { 21 | get 22 | { 23 | var sum = 0; 24 | for (int i = 0; i < PoolArraySize; i++) 25 | sum += _pools[i].Count; 26 | return sum; 27 | } 28 | } 29 | 30 | private static readonly ConcurrentBag[] _pools; 31 | 32 | // Pushes the specified VillageObject to the corresponding pool. 33 | public static void Push(VillageObject obj) 34 | { 35 | GetPool(obj.KindId).Add(obj); 36 | } 37 | 38 | // Tries to get the VillageObject with the corresponding game ID. 39 | public static bool TryPop(int kindId, out VillageObject obj) 40 | { 41 | //return GetPool(gameId).TryTake(out obj); 42 | 43 | obj = default(VillageObject); 44 | var success = GetPool(kindId).TryTake(out obj); 45 | if (success) 46 | obj.ResetVillageObject(); 47 | 48 | return success; 49 | } 50 | 51 | // Returns the pool which corresponds to the specified game ID. 52 | private static ConcurrentBag GetPool(int kindId) 53 | { 54 | // Potential IndexOutOfRangeException here. 55 | return _pools[kindId]; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Cryptography/CoCCrypto.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Cryptography 2 | { 3 | /// 4 | /// Base class of Clash of Clans encryption. 5 | /// 6 | public abstract class CoCCrypto 7 | { 8 | /// 9 | /// Gets the version of the . 10 | /// 11 | public abstract int Version { get; } 12 | 13 | /// 14 | /// Encrypts the provided bytes(plain-text). 15 | /// 16 | /// Bytes to encrypt. 17 | public abstract void Encrypt(ref byte[] data); 18 | 19 | /// 20 | /// Decrypts the provided bytes(cipher-text). 21 | /// 22 | /// Bytes to decrypt. 23 | public abstract void Decrypt(ref byte[] data); 24 | } 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Cryptography/NaCl/Internal/verify_16.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Cryptography.NaCl.Internal 2 | { 3 | internal static class verify_16 4 | { 5 | public static int crypto_verify(byte[] x, int xoffset, byte[] y) 6 | { 7 | int differentbits = 0; 8 | 9 | for (int i = 0; i < 15; i++) 10 | differentbits |= (x[xoffset + i] ^ y[i]) & 0xff; 11 | 12 | return (1 & (int)(((uint)differentbits - 1) >> 8)) - 1; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Cryptography/NaCl/Internal/xsalsa20.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Cryptography.NaCl.Internal 2 | { 3 | internal static class xsalsa20 4 | { 5 | private const int crypto_stream_xsalsa20_ref_KEYBYTES = 32; 6 | private const int crypto_stream_xsalsa20_ref_NONCEBYTES = 24; 7 | 8 | public static readonly byte[] sigma = 9 | { 10 | (byte) 'e', (byte) 'x', (byte) 'p', (byte) 'a', 11 | (byte) 'n', (byte) 'd', (byte) ' ', (byte) '3', 12 | (byte) '2', (byte) '-', (byte) 'b', (byte) 'y', 13 | (byte) 't', (byte) 'e', (byte) ' ', (byte) 'k' 14 | }; 15 | 16 | public static int crypto_stream(byte[] c, int clen, byte[] n, byte[] k) 17 | { 18 | byte[] subkey = new byte[32]; 19 | 20 | hsalsa20.crypto_core(subkey, n, k, sigma); 21 | return salsa20.crypto_stream(c, clen, n, 16, subkey); 22 | } 23 | 24 | public static int crypto_stream_xor(byte[] c, byte[] m, long mlen, byte[] n, byte[] k) 25 | { 26 | byte[] subkey = new byte[32]; 27 | 28 | hsalsa20.crypto_core(subkey, n, k, sigma); 29 | return salsa20.crypto_stream_xor(c, m, (int)mlen, n, 16, subkey); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Cryptography/NaCl/Internal/xsalsa20poly1305.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Cryptography.NaCl.Internal 2 | { 3 | internal static class xsalsa20poly1305 4 | { 5 | public const int crypto_secretbox_KEYBYTES = 32; 6 | public const int crypto_secretbox_NONCEBYTES = 24; 7 | public const int crypto_secretbox_ZEROBYTES = 32; 8 | public const int crypto_secretbox_BOXZEROBYTES = 16; 9 | 10 | public static int crypto_secretbox(byte[] c, byte[] m, long mlen, byte[] n, byte[] k) 11 | { 12 | if (mlen < 32) 13 | return -1; 14 | 15 | xsalsa20.crypto_stream_xor(c, m, mlen, n, k); 16 | poly1305.crypto_onetimeauth(c, 16, c, 32, mlen - 32, c); 17 | 18 | for (int i = 0; i < 16; ++i) 19 | c[i] = 0; 20 | 21 | return 0; 22 | } 23 | 24 | public static int crypto_secretbox_open(byte[] m, byte[] c, long clen, byte[] n, byte[] k) 25 | { 26 | if (clen < 32) 27 | return -1; 28 | 29 | byte[] subkeyp = new byte[32]; 30 | 31 | xsalsa20.crypto_stream(subkeyp, 32, n, k); 32 | 33 | if (poly1305.crypto_onetimeauth_verify(c, 16, c, 32, clen - 32, subkeyp) != 0) 34 | return -1; 35 | 36 | xsalsa20.crypto_stream_xor(m, c, clen, n, k); 37 | 38 | for (int i = 0; i < 32; ++i) 39 | m[i] = 0; 40 | 41 | return 0; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Cryptography/NaCl/SecretBox.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Network.Cryptography.NaCl.Internal; 2 | using System; 3 | using System.Security.Cryptography; 4 | 5 | namespace CoCSharp.Network.Cryptography.NaCl 6 | { 7 | public static class SecretBox 8 | { 9 | public static byte[] Box(byte[] message, byte[] key, byte[] nonce) 10 | { 11 | var paddedChiper = new byte[message.Length + xsalsa20poly1305.crypto_secretbox_ZEROBYTES]; 12 | var paddedMessage = new byte[message.Length + xsalsa20poly1305.crypto_secretbox_ZEROBYTES]; 13 | Buffer.BlockCopy(message, 0, paddedMessage, xsalsa20poly1305.crypto_secretbox_ZEROBYTES, message.Length); 14 | 15 | if (xsalsa20poly1305.crypto_secretbox(paddedChiper, paddedMessage, paddedMessage.Length, nonce, key) != 0) 16 | throw new CryptographicException("Failed to box SecretBox."); 17 | 18 | var chiperLen = paddedChiper.Length - xsalsa20poly1305.crypto_secretbox_BOXZEROBYTES; 19 | var chiper = new byte[chiperLen]; 20 | Buffer.BlockCopy(paddedChiper, xsalsa20poly1305.crypto_secretbox_BOXZEROBYTES, chiper, 0, chiperLen); 21 | return chiper; 22 | } 23 | 24 | public static byte[] Open(byte[] chiper, byte[] key, byte[] nonce) 25 | { 26 | var paddedMessage = new byte[chiper.Length + xsalsa20poly1305.crypto_secretbox_BOXZEROBYTES]; 27 | var paddedChiper = new byte[chiper.Length + xsalsa20poly1305.crypto_secretbox_BOXZEROBYTES]; 28 | Buffer.BlockCopy(chiper, 0, paddedChiper, xsalsa20poly1305.crypto_secretbox_BOXZEROBYTES, chiper.Length); 29 | 30 | if (xsalsa20poly1305.crypto_secretbox_open(paddedMessage, paddedChiper, paddedChiper.Length, nonce, key) != 0) 31 | throw new CryptographicException("Failed to box SecretBox."); 32 | 33 | var messageLen = paddedChiper.Length - xsalsa20poly1305.crypto_secretbox_BOXZEROBYTES; 34 | var message = new byte[messageLen]; 35 | Buffer.BlockCopy(paddedMessage, xsalsa20poly1305.crypto_secretbox_BOXZEROBYTES, message, 0, messageLen); 36 | return message; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Cryptography/UpdateNonceType.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Cryptography 2 | { 3 | /// 4 | /// Defines ways to instruct the to update nonces. 5 | /// 6 | public enum UpdateNonceType 7 | { 8 | /// 9 | /// Instructs the to update the Blake2b nonce. 10 | /// 11 | Blake, 12 | 13 | /// 14 | /// Instructs the to update the decrypt nonce. This can 15 | /// either be rnonce or snonce. 16 | /// 17 | Decrypt, 18 | 19 | /// 20 | /// Instructs the to update the encrypt nonce. This can 21 | /// either be rnonce or snonce. 22 | /// 23 | Encrypt 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/DisconnectedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net.Sockets; 3 | 4 | namespace CoCSharp.Network 5 | { 6 | /// 7 | /// Event argument when gets disconnected. 8 | /// 9 | public class DisconnectedEventArgs : EventArgs 10 | { 11 | /// 12 | /// Initializes a new instance of the class. 13 | /// 14 | public DisconnectedEventArgs(SocketError error) 15 | { 16 | Error = error; 17 | } 18 | 19 | /// 20 | /// Gets or sets the that caused the disconnection. 21 | /// 22 | public SocketError Error { get; private set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Memory/MemoryBlock.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Memory 2 | { 3 | /// 4 | /// Represents a memory block. 5 | /// 6 | public class MemoryBlock 7 | { 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Memory/MemoryBlockPool.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Memory 2 | { 3 | /// 4 | /// Represents a pool of . 5 | /// 6 | public class MemoryBlockPool 7 | { 8 | /// 9 | /// Initializes a new instance of the class. 10 | /// 11 | public MemoryBlockPool() 12 | { 13 | 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Memory/MemorySlab.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Memory 2 | { 3 | /// 4 | /// Represents a memory slab. 5 | /// 6 | public class MemorySlab 7 | { 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Memory/MemorySlabsStream.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Memory 2 | { 3 | /// 4 | /// Stream methods to read from . 5 | /// 6 | public class MemorySlabsStream 7 | { 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/MessageBufferManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net.Sockets; 3 | 4 | namespace CoCSharp.Network 5 | { 6 | [Obsolete] 7 | internal class MessageBufferManager 8 | { 9 | public MessageBufferManager(int receiveCount, int sendCount, int bufferSize) 10 | { 11 | if (receiveCount < 1) 12 | throw new ArgumentOutOfRangeException(nameof(receiveCount), "Receive count cannot be less than 1."); 13 | if (sendCount < 1) 14 | throw new ArgumentOutOfRangeException(nameof(sendCount), "Send count cannot be less than 1."); 15 | if (bufferSize < 1) 16 | throw new ArgumentOutOfRangeException(nameof(bufferSize), "Buffer size cannot be less than 1."); 17 | 18 | _receiveCount = receiveCount; 19 | _sendCount = sendCount; 20 | 21 | BufferIndex = 0; 22 | _bufferSize = bufferSize; 23 | _buffer = new byte[(receiveCount + sendCount) * bufferSize]; 24 | } 25 | 26 | private readonly int _receiveCount; 27 | private readonly int _sendCount; 28 | 29 | internal int BufferIndex; 30 | private readonly int _bufferSize; 31 | private readonly byte[] _buffer; 32 | 33 | public void SetBuffer(SocketAsyncEventArgs args) 34 | { 35 | if (BufferIndex >= _buffer.Length) 36 | { 37 | var message = "Cannot SetBuffer of args because offset '" + BufferIndex + "' is larger than buffer size '" + _buffer.Length + "'."; 38 | throw new InvalidOperationException(message); 39 | } 40 | 41 | args.SetBuffer(_buffer, BufferIndex, _bufferSize); 42 | BufferIndex += _bufferSize; 43 | } 44 | 45 | public void GetBuffer() 46 | { 47 | 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/MessageDirection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Network 4 | { 5 | /// 6 | /// Defines the direction of a . 7 | /// 8 | [Flags] 9 | public enum MessageDirection : byte 10 | { 11 | /// 12 | /// is going to the client. 13 | /// 14 | Client = 2, 15 | 16 | /// 17 | /// is going to the server. 18 | /// 19 | Server = 3 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/MessageFactorySuppressAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Network 4 | { 5 | /// 6 | /// Use this attribute to prevent the to add it 7 | /// in the . This class cannot be inherited. 8 | /// 9 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] 10 | internal sealed class MessageFactorySuppressAttribute : Attribute 11 | { 12 | public MessageFactorySuppressAttribute(bool suppress = true) 13 | { 14 | Suppress = suppress; 15 | } 16 | 17 | public bool Suppress { get; private set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/MessageHeader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Network 4 | { 5 | /// 6 | /// Represents the header of a . 7 | /// 8 | public struct MessageHeader 9 | { 10 | /// 11 | /// Size of a . This field is constant. 12 | /// 13 | public const int Size = 7; 14 | 15 | /// 16 | /// Constructs a new instance of the with the specified 17 | /// message ID, length and version. 18 | /// 19 | /// ID of the . 20 | /// Length of the . 21 | /// Version of the . 22 | public MessageHeader(ushort id, int length, ushort version) 23 | { 24 | if (length < 0 || length > Message.MaxSize) 25 | throw new ArgumentOutOfRangeException(nameof(length), "Length must be non-negative and less or equal to the maximum size of a message."); 26 | 27 | Id = id; 28 | Length = length; 29 | Version = version; 30 | } 31 | 32 | /// 33 | /// ID of the . 34 | /// 35 | public readonly ushort Id; 36 | /// 37 | /// Length of the . 38 | /// 39 | public readonly int Length; 40 | /// 41 | /// Version of the . 42 | /// 43 | public readonly ushort Version; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/MessageProcessor.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Network.Cryptography; 2 | 3 | namespace CoCSharp.Network 4 | { 5 | /// 6 | /// Represents a processor to process incoming and outgoing messages. 7 | /// 8 | public abstract class MessageProcessor 9 | { 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | protected MessageProcessor() 14 | { 15 | // Space 16 | } 17 | 18 | /// 19 | /// Gets the that is going to decrypt incoming and encrypt outgoing 20 | /// messages. 21 | /// 22 | public abstract CoCCrypto Crypto { get; } 23 | 24 | /// 25 | /// Processes the specified chippered array of bytes and returns 26 | /// the resulting . 27 | /// 28 | /// Header of the message. 29 | /// Chippered array of bytes representing a message to process. 30 | /// Raw array of bytes representing the message. 31 | /// Plaintext representation of the data read. 32 | /// Resulting . 33 | public abstract Message ProcessIncoming(MessageHeader header, BufferStream stream, ref byte[] raw, ref byte[] plaintext); 34 | 35 | /// 36 | /// Processes the specified and returns 37 | /// the resulting chippered array of bytes. 38 | /// 39 | /// to process. 40 | /// Resulting chippered array of bytes. 41 | public abstract byte[] ProcessOutgoing(Message message); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/MessageProcessorRC4.cs: -------------------------------------------------------------------------------- 1 | //using System; 2 | //using CoCSharp.Network.Cryptography; 3 | 4 | //namespace CoCSharp.Network 5 | //{ 6 | // public class MessageProcessorRC4 : MessageProcessor 7 | // { 8 | // public override CoCCrypto Crypto 9 | // { 10 | // get 11 | // { 12 | // throw new NotImplementedException(); 13 | // } 14 | // } 15 | 16 | // public override Message ProcessIncoming(MessageHeader header, byte[] chiper, ref byte[] plaintext) 17 | // { 18 | // throw new NotImplementedException(); 19 | // } 20 | 21 | // public override byte[] ProcessOutgoing(Message message) 22 | // { 23 | // throw new NotImplementedException(); 24 | // } 25 | // } 26 | //} 27 | 28 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/MessageReceivedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Network 4 | { 5 | /// 6 | /// Provides arguments data for message received event. 7 | /// 8 | public class MessageReceivedEventArgs : EventArgs 9 | { 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | public MessageReceivedEventArgs() 14 | { 15 | // Space 16 | } 17 | 18 | /// 19 | /// Gets or sets the that has been 20 | /// received. 21 | /// 22 | public Message Message { get; set; } 23 | 24 | /// 25 | /// Gets or sets the that occurred during 26 | /// the reading of the . 27 | /// 28 | /// Returns null if no error occurred during reading. 29 | /// 30 | public Exception Exception { get; set; } 31 | 32 | /// 33 | /// Gets or sets whether the received was fully read. 34 | /// 35 | public bool FullyRead { get; set; } 36 | 37 | /// 38 | /// Gets or sets the bytes body that was decrypted 39 | /// from the network. 40 | /// 41 | public byte[] Plaintext { get; set; } 42 | 43 | /// 44 | /// Gets or sets the raw bytes that was received from 45 | /// the network. This includes the header and the body encrypted. 46 | /// 47 | public byte[] Raw { get; set; } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/MessageSentEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Network 4 | { 5 | /// 6 | /// Provides arguments data for message sent event. 7 | /// 8 | public class MessageSentEventArgs : EventArgs 9 | { 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | public MessageSentEventArgs() 14 | { 15 | // Space 16 | } 17 | 18 | /// 19 | /// Gets or sets the that has been 20 | /// sent. 21 | /// 22 | public Message Message { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/AllianceChatMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Network.Messages 4 | { 5 | /// 6 | /// Message that is sent by the client to the server to tell it 7 | /// that it has sent a message to the alliance chat. 8 | /// 9 | public class AllianceChatMessage : Message 10 | { 11 | /// 12 | /// Initializes a new instance of the class. 13 | /// 14 | public AllianceChatMessage() 15 | { 16 | // Space 17 | } 18 | 19 | /// 20 | /// Gets the ID of the . 21 | /// 22 | public override ushort Id => 14315; 23 | 24 | /// 25 | /// Message that should be sent to the alliance chat. 26 | /// 27 | public string MessageText; 28 | 29 | /// 30 | /// Reads the from the specified . 31 | /// 32 | /// 33 | /// that will be used to read the . 34 | /// 35 | /// is null. 36 | public override void ReadMessage(MessageReader reader) 37 | { 38 | ThrowIfReaderNull(reader); 39 | 40 | MessageText = reader.ReadString(); 41 | } 42 | 43 | /// 44 | /// Writes the to the specified . 45 | /// 46 | /// 47 | /// that will be used to write the . 48 | /// 49 | /// is null. 50 | public override void WriteMessage(MessageWriter writer) 51 | { 52 | ThrowIfWriterNull(writer); 53 | 54 | writer.Write(MessageText); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/AllianceDataRequestMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Network.Messages 4 | { 5 | /// 6 | /// Message that is sent by the client to the server to request 7 | /// for the data of an alliance/clan. 8 | /// 9 | public class AllianceDataRequestMessage : Message 10 | { 11 | /// 12 | /// Initializes a new instance of the class. 13 | /// 14 | public AllianceDataRequestMessage() 15 | { 16 | // Space 17 | } 18 | 19 | /// 20 | /// Gets the ID of the . 21 | /// 22 | public override ushort Id { get { return 14302; } } 23 | 24 | /// 25 | /// ID of the clan whose data was requested. 26 | /// 27 | public long ClanId; 28 | 29 | /// 30 | /// Reads the from the specified . 31 | /// 32 | /// 33 | /// that will be used to read the . 34 | /// 35 | /// is null. 36 | public override void ReadMessage(MessageReader reader) 37 | { 38 | ThrowIfReaderNull(reader); 39 | 40 | ClanId = reader.ReadInt64(); 41 | } 42 | 43 | /// 44 | /// Writes the to the specified . 45 | /// 46 | /// 47 | /// that will be used to write the . 48 | /// 49 | /// is null. 50 | public override void WriteMessage(MessageWriter writer) 51 | { 52 | ThrowIfWriterNull(writer); 53 | 54 | writer.Write(ClanId); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/AttackNpcMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Network.Messages 4 | { 5 | /// 6 | /// Message that is sent by the client to server to tell 7 | /// it that an NPC village is being attacked. 8 | /// 9 | public class AttackNpcMessage : Message 10 | { 11 | /// 12 | /// Initializes a new instance of the class. 13 | /// 14 | public AttackNpcMessage() 15 | { 16 | // Space 17 | } 18 | 19 | /// 20 | /// Gets the ID of the . 21 | /// 22 | public override ushort Id { get { return 14134; } } 23 | 24 | /// 25 | /// NPC ID that was attacked. 26 | /// 27 | public int NpcId; 28 | 29 | /// 30 | /// Reads the from the specified . 31 | /// 32 | /// 33 | /// that will be used to read the . 34 | /// 35 | /// is null. 36 | public override void ReadMessage(MessageReader reader) 37 | { 38 | ThrowIfReaderNull(reader); 39 | 40 | NpcId = reader.ReadInt32(); 41 | } 42 | 43 | /// 44 | /// Writes the to the specified . 45 | /// 46 | /// 47 | /// that will be used to write the . 48 | /// 49 | /// is null. 50 | public override void WriteMessage(MessageWriter writer) 51 | { 52 | ThrowIfWriterNull(writer); 53 | 54 | writer.Write(NpcId); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/AvatarStreamEntry.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Messages 2 | { 3 | /// 4 | /// Represents an avatar stream entry. 5 | /// 6 | public abstract class AvatarStreamEntry : StreamEntry 7 | { 8 | // Space 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/ChatAllianceStreamEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Network.Messages 4 | { 5 | /// 6 | /// Stream entry indicating chat messages sent in 7 | /// the alliance chat. 8 | /// 9 | public class ChatAllianceStreamEntry : AllianceStreamEntry 10 | { 11 | /// 12 | /// Initializes a new instance of the class. 13 | /// 14 | public ChatAllianceStreamEntry() 15 | { 16 | //space 17 | } 18 | 19 | /// 20 | /// Message that was sent. 21 | /// 22 | public string MessageText; 23 | 24 | /// 25 | /// Get the ID of the 26 | /// 27 | public override int Id => 2; 28 | 29 | /// 30 | /// Reads the from the specified . 31 | /// 32 | /// 33 | /// that will be used to read the . 34 | /// 35 | /// is null. 36 | public override void ReadStreamEntry(MessageReader reader) 37 | { 38 | base.ReadStreamEntry(reader); 39 | 40 | MessageText = reader.ReadString(); 41 | } 42 | 43 | /// 44 | /// Writes the to the specified . 45 | /// 46 | /// 47 | /// that will be used to write the . 48 | /// 49 | /// is null. 50 | public override void WriteStreamEntry(MessageWriter writer) 51 | { 52 | base.WriteStreamEntry(writer); 53 | 54 | writer.Write(MessageText); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/ChatMessageClientMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Network.Messages 4 | { 5 | /// 6 | /// Message that is sent by the client to the server to send a message to the lobby chat. The 7 | /// server then replies with a . 8 | /// 9 | public class ChatMessageClientMessage : Message 10 | { 11 | /// 12 | /// Initializes a new instance of the class. 13 | /// 14 | public ChatMessageClientMessage() 15 | { 16 | // Space 17 | } 18 | 19 | /// 20 | /// Gets the ID of the . 21 | /// 22 | public override ushort Id { get { return 14715; } } 23 | 24 | /// 25 | /// Message that will be sent to the lobby chat. 26 | /// 27 | public string TextMessage; 28 | 29 | /// 30 | /// Reads the from the specified . 31 | /// 32 | /// 33 | /// that will be used to read the . 34 | /// 35 | /// is null. 36 | public override void ReadMessage(MessageReader reader) 37 | { 38 | ThrowIfReaderNull(reader); 39 | 40 | TextMessage = reader.ReadString(); 41 | } 42 | 43 | /// 44 | /// Writes the to the specified . 45 | /// 46 | /// 47 | /// that will be used to write the . 48 | /// 49 | /// is null. 50 | public override void WriteMessage(MessageWriter writer) 51 | { 52 | ThrowIfWriterNull(writer); 53 | 54 | writer.Write(TextMessage); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/ClanMessageComponent.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Logic; 2 | using System; 3 | 4 | namespace CoCSharp.Network.Messages 5 | { 6 | /// 7 | /// Represents an 's clan data sent 8 | /// in the networking protocol. 9 | /// 10 | public class ClanMessageComponent : MessageComponent 11 | { 12 | /// 13 | /// Initializes a new instance of the class. 14 | /// 15 | public ClanMessageComponent() 16 | { 17 | // Space 18 | } 19 | 20 | /// 21 | /// Clan ID. 22 | /// 23 | public long Id; 24 | /// 25 | /// Clan name. 26 | /// 27 | public string Name; 28 | /// 29 | /// Clan badge data. 30 | /// 31 | public int Badge; 32 | /// 33 | /// Clan member role. 34 | /// 35 | public ClanMemberRole Role; 36 | /// 37 | /// Clan level. 38 | /// 39 | public int Level; 40 | 41 | // Unknown1 & Unknown2 does not actually belong to this component but AvatarMessageComponent. 42 | 43 | /// 44 | /// Unknown byte 1. 45 | /// 46 | public byte Unknown1; 47 | 48 | /// 49 | /// Unknown long 2. 50 | /// 51 | public long Unknown2; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/HandshakeSuccessMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Network.Messages 4 | { 5 | /// 6 | /// Message that is sent by the server to the client after 7 | /// the client sends a . 8 | /// 9 | public class HandshakeSuccessMessage : Message 10 | { 11 | /// 12 | /// Initializes a new instance of the class. 13 | /// 14 | public HandshakeSuccessMessage() 15 | { 16 | // Space 17 | } 18 | 19 | /// 20 | /// Session key. 21 | /// 22 | public byte[] SessionKey; 23 | 24 | /// 25 | /// Gets the ID of the . 26 | /// 27 | public override ushort Id { get { return 20100; } } 28 | 29 | /// 30 | /// Reads the from the specified . 31 | /// 32 | /// 33 | /// that will be used to read the . 34 | /// 35 | /// is null. 36 | public override void ReadMessage(MessageReader reader) 37 | { 38 | ThrowIfReaderNull(reader); 39 | 40 | SessionKey = reader.ReadBytes(); 41 | } 42 | 43 | /// 44 | /// Writes the to the specified . 45 | /// 46 | /// 47 | /// that will be used to write the . 48 | /// 49 | /// is null. 50 | public override void WriteMessage(MessageWriter writer) 51 | { 52 | ThrowIfWriterNull(writer); 53 | 54 | writer.Write(SessionKey, true); // the byte array is prefixed 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/JoinAllianceMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Network.Messages 4 | { 5 | /// 6 | /// Message that is sent by the client to the server 7 | /// to tell it that it joined an alliance. 8 | /// 9 | public class JoinAllianceMessage : Message 10 | { 11 | /// 12 | /// Initializes a new instance of the class. 13 | /// 14 | public JoinAllianceMessage() 15 | { 16 | // Space 17 | } 18 | 19 | /// 20 | /// Gets the ID of the . 21 | /// 22 | public override ushort Id { get { return 14305; } } 23 | 24 | /// 25 | /// ID of the clan the client joined. 26 | /// 27 | public long ClanId; 28 | 29 | /// 30 | /// Reads the from the specified . 31 | /// 32 | /// 33 | /// that will be used to read the . 34 | /// 35 | /// is null. 36 | public override void ReadMessage(MessageReader reader) 37 | { 38 | ThrowIfReaderNull(reader); 39 | 40 | ClanId = reader.ReadInt64(); 41 | } 42 | 43 | /// 44 | /// Writes the to the specified . 45 | /// 46 | /// 47 | /// that will be used to write the . 48 | /// 49 | /// is null. 50 | public override void WriteMessage(MessageWriter writer) 51 | { 52 | ThrowIfWriterNull(writer); 53 | 54 | writer.Write(ClanId); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/JoinableAllianceListRequestMessage.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Messages 2 | { 3 | /// 4 | /// Message that is sent by the client to the server to 5 | /// request for alliances that it is capable of joining. 6 | /// 7 | public class JoinableAllianceListRequestMessage : Message 8 | { 9 | /// 10 | /// Initializes a new instance of the class. 11 | /// 12 | public JoinableAllianceListRequestMessage() 13 | { 14 | // Space 15 | } 16 | 17 | /// 18 | /// Gets the ID of the . 19 | /// 20 | public override ushort Id { get { return 14303; } } 21 | 22 | /// 23 | /// Reads the from the specified . 24 | /// 25 | /// 26 | /// that will be used to read the . 27 | /// 28 | public override void ReadMessage(MessageReader reader) 29 | { 30 | // Space 31 | } 32 | 33 | /// 34 | /// Writes the to the specified . 35 | /// 36 | /// 37 | /// that will be used to write the . 38 | /// 39 | public override void WriteMessage(MessageWriter writer) 40 | { 41 | // Space 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/KeepAliveRequestMessage.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Messages 2 | { 3 | /// 4 | /// Empty message that is sent by the client to the server. The server 5 | /// must reply with a . 6 | /// 7 | public class KeepAliveRequestMessage : Message 8 | { 9 | /// 10 | /// Initializes a new instance of the class. 11 | /// 12 | public KeepAliveRequestMessage() 13 | { 14 | // Space 15 | } 16 | 17 | /// 18 | /// Gets the ID of the . 19 | /// 20 | public override ushort Id { get { return 10108; } } 21 | 22 | /// 23 | /// Reads the from the specified . 24 | /// 25 | /// 26 | /// that will be used to read the . 27 | /// 28 | public override void ReadMessage(MessageReader reader) 29 | { 30 | // Space 31 | } 32 | 33 | /// 34 | /// Writes the to the specified . 35 | /// 36 | /// 37 | /// that will be used to write the . 38 | /// 39 | public override void WriteMessage(MessageWriter writer) 40 | { 41 | // Space 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/KeepAliveResponseMessage.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Messages 2 | { 3 | /// 4 | /// Empty message that is sent by the server to the client 5 | /// after every sent by the client. 6 | /// 7 | public class KeepAliveResponseMessage : Message 8 | { 9 | /// 10 | /// Initializes a new instance of the class. 11 | /// 12 | public KeepAliveResponseMessage() 13 | { 14 | // Space 15 | } 16 | 17 | /// 18 | /// Gets the ID of the . 19 | /// 20 | public override ushort Id { get { return 20108; } } 21 | 22 | /// 23 | /// Reads the from the specified . 24 | /// 25 | /// 26 | /// that will be used to read the . 27 | /// 28 | public override void ReadMessage(MessageReader reader) 29 | { 30 | // Space 31 | } 32 | 33 | /// 34 | /// Writes the to the specified . 35 | /// 36 | /// 37 | /// that will be used to write the . 38 | /// 39 | public override void WriteMessage(MessageWriter writer) 40 | { 41 | // Space 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/LeaveAllianceMessage.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Messages 2 | { 3 | /// 4 | /// Message that is sent by the client to the server to tell 5 | /// it that it has left its alliance. 6 | /// 7 | public class LeaveAllianceMessage : Message 8 | { 9 | /// 10 | /// Initializes a new instance of the class. 11 | /// 12 | public LeaveAllianceMessage() 13 | { 14 | // Space 15 | } 16 | 17 | /// 18 | /// Gets the ID of the . 19 | /// 20 | public override ushort Id { get { return 14308; } } 21 | 22 | /// 23 | /// Reads the from the specified . 24 | /// 25 | /// 26 | /// that will be used to read the . 27 | /// 28 | public override void ReadMessage(MessageReader reader) 29 | { 30 | // Space 31 | } 32 | 33 | /// 34 | /// Writes the to the specified . 35 | /// 36 | /// 37 | /// that will be used to write the . 38 | /// 39 | public override void WriteMessage(MessageWriter writer) 40 | { 41 | // Space 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/MoveVillageObjectMessageComponent.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Logic; 2 | using CoCSharp.Logic.Commands; 3 | using CoCSharp.Network; 4 | 5 | namespace CoCSharp.Data 6 | { 7 | //TODO: Figure something better for it. 8 | 9 | /// 10 | /// Represents data about move village object sent 11 | /// in and . 12 | /// 13 | public class MoveVillageObjectMessageComponent : MessageComponent 14 | { 15 | /// 16 | /// Initializes a new instance of the class. 17 | /// 18 | public MoveVillageObjectMessageComponent() 19 | { 20 | // Space 21 | } 22 | 23 | /// 24 | /// X coordinates of the new position. 25 | /// 26 | public int X; 27 | /// 28 | /// Y coordinates of the new position. 29 | /// 30 | public int Y; 31 | /// 32 | /// game ID in a that 33 | /// was moved. 34 | /// 35 | public int VillageObjectGameId; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/ReturnHomeMessage.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Messages 2 | { 3 | /// 4 | /// Message that is sent by the client to server to tell 5 | /// it that it wants to return home; the server then should 6 | /// send an . 7 | /// 8 | public class ReturnHomeMessage : Message 9 | { 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | public ReturnHomeMessage() 14 | { 15 | // Space 16 | } 17 | 18 | /// 19 | /// Unknown long 1. 20 | /// 21 | public long Unknown1; 22 | 23 | /// 24 | /// Gets the ID of the . 25 | /// 26 | public override ushort Id { get { return 14101; } } 27 | 28 | /// 29 | /// Reads the from the specified . 30 | /// 31 | /// 32 | /// that will be used to read the . 33 | /// 34 | public override void ReadMessage(MessageReader reader) 35 | { 36 | Unknown1 = reader.ReadInt64(); 37 | } 38 | 39 | /// 40 | /// Writes the to the specified . 41 | /// 42 | /// 43 | /// that will be used to write the . 44 | /// 45 | public override void WriteMessage(MessageWriter writer) 46 | { 47 | writer.Write(Unknown1); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/ServerErrorMessage.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Messages 2 | { 3 | /// 4 | /// Message that is sent by the server to the client to tell 5 | /// it an error has occurred. 6 | /// 7 | public class ServerErrorMessage : Message 8 | { 9 | /// 10 | /// Initializes a new instance of the class. 11 | /// 12 | public ServerErrorMessage() 13 | { 14 | // Space 15 | } 16 | 17 | /// 18 | /// Gets the ID of the . 19 | /// 20 | public override ushort Id { get { return 24115; } } 21 | 22 | /// 23 | /// Error message. 24 | /// 25 | public string ErrorMessage; 26 | 27 | /// 28 | /// Reads the from the specified . 29 | /// 30 | /// 31 | /// that will be used to read the . 32 | /// 33 | public override void ReadMessage(MessageReader reader) 34 | { 35 | ThrowIfReaderNull(reader); 36 | 37 | ErrorMessage = reader.ReadString(); 38 | } 39 | 40 | /// 41 | /// Writes the to the specified . 42 | /// 43 | /// 44 | /// that will be used to write the . 45 | /// 46 | public override void WriteMessage(MessageWriter writer) 47 | { 48 | ThrowIfWriterNull(writer); 49 | 50 | writer.Write(ErrorMessage); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/ServerShutdownInfoMessage.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Messages 2 | { 3 | /// 4 | /// Message that is sent by the server to the client to tell 5 | /// it that the server is going to be in maintenance. 6 | /// 7 | public class ServerShutdownInfoMessage : Message 8 | { 9 | /// 10 | /// Initializes a new instance of the class. 11 | /// 12 | public ServerShutdownInfoMessage() 13 | { 14 | // Space 15 | } 16 | 17 | /// 18 | /// Gets the ID of the . 19 | /// 20 | public override ushort Id { get { return 20161; } } 21 | 22 | /// 23 | /// Reads the from the specified . 24 | /// 25 | /// 26 | /// that will be used to read the . 27 | /// 28 | public override void ReadMessage(MessageReader reader) 29 | { 30 | // Space 31 | } 32 | 33 | /// 34 | /// Writes the to the specified . 35 | /// 36 | /// 37 | /// that will be used to write the . 38 | /// 39 | public override void WriteMessage(MessageWriter writer) 40 | { 41 | // Space 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/StreamEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Network.Messages 4 | { 5 | /// 6 | /// Represents a stream entry. 7 | /// 8 | public abstract class StreamEntry 9 | { 10 | /// 11 | /// Gets the ID of the . 12 | /// 13 | public abstract int Id { get; } 14 | 15 | /// 16 | /// Reads the from the specified . 17 | /// 18 | /// 19 | /// that will be used to read the . 20 | /// 21 | public virtual void ReadStreamEntry(MessageReader reader) 22 | { 23 | // Space 24 | } 25 | 26 | /// 27 | /// Writes the to the specified . 28 | /// 29 | /// 30 | /// that will be used to write the . 31 | /// 32 | public virtual void WriteStreamEntry(MessageWriter writer) 33 | { 34 | // Space 35 | } 36 | 37 | internal void ThrowIfReaderNull(MessageReader reader) 38 | { 39 | if (reader == null) 40 | throw new ArgumentNullException(nameof(reader)); 41 | } 42 | 43 | internal void ThrowIfWriterNull(MessageWriter writer) 44 | { 45 | if (writer == null) 46 | throw new ArgumentNullException(nameof(writer)); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/Unknown11AllianceStreamEntry.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Messages 2 | { 3 | public class Unknown11AllianceStreamEntry : AllianceStreamEntry 4 | { 5 | public Unknown11AllianceStreamEntry() 6 | { 7 | // Space 8 | } 9 | 10 | public override int Id => 11; 11 | 12 | public string UnknownJson; 13 | 14 | public override void ReadStreamEntry(MessageReader reader) 15 | { 16 | base.ReadStreamEntry(reader); 17 | 18 | UnknownJson = reader.ReadString(); 19 | var k = reader.ReadInt32(); 20 | var d = reader.ReadByte(); 21 | var k1 = reader.ReadInt32(); 22 | if (d == 0) 23 | { 24 | var d1 = reader.ReadByte(); 25 | } 26 | var d2 = reader.ReadByte(); 27 | var k2 = reader.ReadInt32(); 28 | } 29 | 30 | public override void WriteStreamEntry(MessageWriter writer) 31 | { 32 | base.WriteStreamEntry(writer); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/Messages/UnknownMessage.cs: -------------------------------------------------------------------------------- 1 | namespace CoCSharp.Network.Messages 2 | { 3 | /// 4 | /// Represents a Clash of Clans message that is not 5 | /// implemented in CoCSharp. 6 | /// 7 | public class UnknownMessage : Message 8 | { 9 | /// 10 | /// Gets the ID of the . 11 | /// 12 | public override ushort Id { get; set; } 13 | 14 | /// 15 | /// Gets the version of the . 16 | /// 17 | public override ushort Version { get; set; } 18 | 19 | /// 20 | /// Gets the length in bytes of the . 21 | /// 22 | public int Length { get; set; } 23 | 24 | /// 25 | /// Byte array that contains the raw encrypted bytes. 26 | /// 27 | public byte[] EncryptedBytes; 28 | /// 29 | /// Byte array that contains the raw decrypted bytes. 30 | /// 31 | public byte[] DecryptedBytes; 32 | 33 | /// 34 | /// Reads the from the specified . 35 | /// 36 | /// 37 | /// that will be used to read the . 38 | /// 39 | public override void ReadMessage(MessageReader reader) 40 | { 41 | DecryptedBytes = reader.ReadBytes(Length); 42 | } 43 | 44 | /// 45 | /// Writes the to the specified . 46 | /// 47 | /// 48 | /// that will be used to write the . 49 | /// 50 | public override void WriteMessage(MessageWriter writer) 51 | { 52 | writer.Write(DecryptedBytes); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/NetworkManagerAsyncStatistics.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | 3 | namespace CoCSharp.Network 4 | { 5 | /// 6 | /// Provides statistics for . This is mostly for debugging 7 | /// purposes. 8 | /// 9 | public class NetworkManagerAsyncStatistics 10 | { 11 | private static int s_nextTokenId; 12 | internal static int NextTokenId => ++s_nextTokenId; 13 | 14 | #region Constructors 15 | /// 16 | /// Initializes a new instance of the class. 17 | /// 18 | public NetworkManagerAsyncStatistics() 19 | { 20 | // Space 21 | } 22 | #endregion 23 | 24 | #region Fields & Properties 25 | internal long _totalSent; 26 | internal long _totalReceived; 27 | internal long _totalMessagesSent; 28 | internal long _totalMessagesReceived; 29 | 30 | /// 31 | /// Gets the total number of bytes transfered. That is the 32 | /// total number of bytes sent and received. 33 | /// 34 | public long TotalByteTransfered => TotalByteSent + TotalByteReceived; 35 | 36 | /// 37 | /// Gets the total number of bytes sent. 38 | /// 39 | public long TotalByteSent => Thread.VolatileRead(ref _totalSent); 40 | 41 | /// 42 | /// Gets the total number of bytes received. 43 | /// 44 | public long TotalByteReceived => Thread.VolatileRead(ref _totalReceived); 45 | 46 | /// 47 | /// Gets the total number of messages sent. 48 | /// 49 | public long TotalMessagesSent => Thread.VolatileRead(ref _totalMessagesSent); 50 | 51 | /// 52 | /// Gets the total number of messages received. 53 | /// 54 | public long TotalMessagesReceived => Thread.VolatileRead(ref _totalMessagesReceived); 55 | #endregion 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/SocketAsyncEventArgsPool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Net.Sockets; 5 | 6 | namespace CoCSharp.Network 7 | { 8 | [DebuggerDisplay("Count = {Count}")] 9 | internal sealed class SocketAsyncEventArgsPool : IDisposable 10 | { 11 | public SocketAsyncEventArgsPool(int capacity) 12 | { 13 | if (capacity < 1) 14 | throw new ArgumentOutOfRangeException("capacity", "capacity cannot be less that 1."); 15 | 16 | Capacity = capacity; 17 | _lock = new object(); 18 | _pool = new Stack(capacity); 19 | } 20 | 21 | private bool _disposed; 22 | private readonly object _lock; 23 | private readonly Stack _pool; 24 | 25 | public int Capacity { get; private set; } 26 | 27 | public int Count { get { return _pool.Count; } } 28 | 29 | public SocketAsyncEventArgs Pop() 30 | { 31 | if (_disposed) 32 | throw new ObjectDisposedException(null, "Cannot Pop because the SocketAsyncEventArgsPool was disposed."); 33 | 34 | lock (_lock) 35 | { 36 | if (_pool.Count == 0) 37 | return null; 38 | 39 | return _pool.Pop(); 40 | } 41 | } 42 | 43 | public void Push(SocketAsyncEventArgs args) 44 | { 45 | if (_disposed) 46 | throw new ObjectDisposedException(null, "Cannot Push because the SocketAsyncEventArgsPool was disposed."); 47 | 48 | lock (_lock) 49 | { 50 | // Resize the capacity of the pool. 51 | if (Count >= Capacity) 52 | Capacity++; 53 | 54 | _pool.Push(args); 55 | } 56 | } 57 | 58 | public void Dispose() 59 | { 60 | if (!_disposed) 61 | { 62 | for (int i = 0; i < _pool.Count; i++) 63 | { 64 | var args = _pool.Pop(); 65 | args.Dispose(); 66 | } 67 | _disposed = true; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/CoCSharp/Network/StreamEntrySuppressAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp.Network 4 | { 5 | /// 6 | /// Use this attribute to prevent the to add it 7 | /// in the 8 | /// or . This class cannot be inherited. 9 | /// 10 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] 11 | internal sealed class StreamEntrySuppressAttribute : Attribute 12 | { 13 | public StreamEntrySuppressAttribute(bool suppress = true) 14 | { 15 | Suppress = suppress; 16 | } 17 | 18 | public bool Suppress { get; private set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/CoCSharp/Pool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Threading; 4 | 5 | namespace CoCSharp 6 | { 7 | [DebuggerDisplay("Count = {Count}")] 8 | internal class Pool 9 | { 10 | public Pool(int capacity) 11 | { 12 | if (capacity < 0) 13 | throw new ArgumentOutOfRangeException(); 14 | 15 | _buffer = new T[capacity]; 16 | } 17 | 18 | private T[] _buffer; 19 | private int _ptr; 20 | 21 | public T this[int index] => _buffer[index]; 22 | 23 | public int Count => Thread.VolatileRead(ref _ptr); 24 | 25 | public void Push(T obj) 26 | { 27 | lock (_buffer) 28 | { 29 | _buffer[_ptr++] = obj; 30 | 31 | if (_ptr == _buffer.Length) 32 | Array.Resize(ref _buffer, _buffer.Length * 2); 33 | } 34 | } 35 | 36 | public T Pop() 37 | { 38 | lock (_buffer) 39 | { 40 | // Avoid going out of bound. 41 | if (_ptr <= 0) 42 | return default(T); 43 | 44 | var value = _buffer[--_ptr]; 45 | 46 | // Reset buffer value. 47 | _buffer[_ptr] = default(T); 48 | return value; 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/CoCSharp/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Make sure that we can test it. 6 | [assembly: InternalsVisibleTo("CoCSharp.Test")] 7 | [assembly: InternalsVisibleTo("CoCSharp.Benchmark")] 8 | 9 | // General Information about an assembly is controlled through the following 10 | // set of attributes. Change these attribute values to modify the information 11 | // associated with an assembly. 12 | [assembly: AssemblyTitle("CoCSharp")] 13 | [assembly: AssemblyDescription("Clash of Clans library written in .NET")] 14 | [assembly: AssemblyConfiguration("")] 15 | [assembly: AssemblyCompany("")] 16 | [assembly: AssemblyProduct("CoCSharp")] 17 | [assembly: AssemblyCopyright("Copyright © 2015")] 18 | [assembly: AssemblyTrademark("")] 19 | [assembly: AssemblyCulture("")] 20 | 21 | // Setting ComVisible to false makes the types in this assembly not visible 22 | // to COM components. If you need to access a type in this assembly from 23 | // COM, set the ComVisible attribute to true on that type. 24 | [assembly: ComVisible(false)] 25 | 26 | // The following GUID is for the ID of the typelib if this project is exposed to COM 27 | [assembly: Guid("7481e33e-b214-421b-8f9b-a812958395dd")] 28 | 29 | // Version information for an assembly consists of the following four values: 30 | // 31 | // Major Version 32 | // Minor Version 33 | // Build Number 34 | // Revision 35 | // 36 | // You can specify all the values or you can default the Build and Revision Numbers 37 | // by using the '*' as shown below: 38 | // [assembly: AssemblyVersion("1.0.*")] 39 | [assembly: AssemblyVersion("1.0.0.0")] 40 | [assembly: AssemblyFileVersion("1.0.0.0")] 41 | -------------------------------------------------------------------------------- /src/CoCSharp/TimeUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoCSharp 4 | { 5 | internal class TimeUtils 6 | { 7 | public const double TickDuration = (1d / 60d) * 1000d; 8 | 9 | private static readonly DateTime UnixTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 10 | 11 | public static int UnixUtcNow 12 | { 13 | get { return (int)ToUnixTimestamp(DateTime.UtcNow); } 14 | } 15 | 16 | public static DateTime FromUnixTimestamp(double unixTimestamp) 17 | { 18 | return UnixTime.AddSeconds(unixTimestamp); 19 | } 20 | 21 | public static double ToUnixTimestamp(DateTime time) 22 | { 23 | return (time - UnixTime).TotalSeconds; 24 | } 25 | 26 | public static DateTime FromJavaTimestamp(double javaTimestamp) 27 | { 28 | return UnixTime.AddSeconds(javaTimestamp / 1000); 29 | } 30 | 31 | public static double ToJavaTimestamp(DateTime time) 32 | { 33 | return (time - UnixTime).TotalSeconds * 1000; 34 | } 35 | 36 | public static int ToTick(TimeSpan duration) 37 | { 38 | return (int)(duration.TotalMilliseconds / TickDuration); 39 | } 40 | 41 | public static int ToTick(int duration) 42 | { 43 | return (int)(duration * 1000d / TickDuration); 44 | } 45 | 46 | public static double FromTick(int tick) 47 | { 48 | return ((tick * TickDuration) / 1000d); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/CoCSharp/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /tests/Csv/CsvConvertTests.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Csv; 2 | using CoCSharp.Data.Models; 3 | using NUnit.Framework; 4 | using System; 5 | using System.IO; 6 | 7 | namespace CoCSharp.Test.Csv 8 | { 9 | [TestFixture] 10 | public class CsvConvertTests 11 | { 12 | private readonly string _tablePath = Path.Combine(TestUtils.CsvDirectory, "buildings.csv"); 13 | private CsvTable _table; 14 | 15 | [SetUp] 16 | public void SetUp() 17 | { 18 | _table = new CsvTable(_tablePath); 19 | } 20 | 21 | [Test] 22 | public void Deserialize_InvalidArgs_Exception() 23 | { 24 | Assert.Throws(() => CsvConvert.Deserialize(null, null)); 25 | Assert.Throws(() => CsvConvert.Deserialize(_table, null)); 26 | Assert.Throws(() => CsvConvert.Deserialize(_table, typeof(TestType))); 27 | Assert.Throws(() => CsvConvert.Deserialize(_table, typeof(CsvData))); 28 | } 29 | 30 | [Test] 31 | public void Deserialize_ReturnType() 32 | { 33 | var table = CsvConvert.Deserialize(_table, typeof(BuildingData)); 34 | Assert.IsInstanceOf>(table); 35 | } 36 | 37 | private class TestType 38 | { 39 | // Space 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/Csv/CsvDataColumnCollectionTests.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Csv; 2 | using NUnit.Framework; 3 | 4 | namespace CoCSharp.Test.Csv 5 | { 6 | [TestFixture] 7 | public class CsvDataColumnCollectionTests 8 | { 9 | private CsvDataTable _table; 10 | 11 | [SetUp] 12 | public void Setup() 13 | { 14 | _table = new CsvDataTable(); 15 | } 16 | 17 | [Test] 18 | public void Add_Column_DataLevel_IsUpdated() 19 | { 20 | var column = new CsvDataColumn(); 21 | Assert.Null(column.Table); 22 | Assert.AreEqual(-1, column.DataLevel); 23 | 24 | _table.Columns.Add(column); 25 | 26 | Assert.AreSame(column.Table, _table); 27 | Assert.AreEqual(0, column.DataLevel); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/Csv/CsvDataRowRefTests.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Csv; 2 | using NUnit.Framework; 3 | using System; 4 | 5 | namespace CoCSharp.Test.Csv 6 | { 7 | [TestFixture] 8 | public class CsvDataRowRefTests 9 | { 10 | [Test] 11 | public void Constructors_InvalidArgs_Exception() 12 | { 13 | Assert.Throws(() => new CsvDataRowRef(-1)); 14 | Assert.Throws(() => new CsvDataRowRef(10003)); 15 | 16 | Assert.Throws(() => new CsvDataRowRef(-1, 2)); 17 | Assert.Throws(() => new CsvDataRowRef(1, -2)); 18 | Assert.Throws(() => new CsvDataRowRef(1, 10000000)); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/Csv/CsvDataRowTests.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Csv; 2 | using NUnit.Framework; 3 | using System; 4 | 5 | namespace CoCSharp.Test.Csv 6 | { 7 | [TestFixture] 8 | public class CsvDataRowTests 9 | { 10 | private CsvDataTable _table; 11 | private CsvDataRow _row; 12 | 13 | [SetUp] 14 | public void SetUp() 15 | { 16 | _table = new CsvDataTable(); 17 | _row = _table.NewRow("LeRow"); 18 | } 19 | 20 | [TestCase(0, ExpectedResult = null)] 21 | [TestCase(1337, ExpectedResult = null)] 22 | [TestCase(int.MaxValue, ExpectedResult = null)] 23 | public CsvData Indexer_Getter_Column_AtIndex_DoesNot_Exists_ReturnsNull(int index) 24 | { 25 | return _row[index]; 26 | } 27 | 28 | [Test] 29 | public void Indexer_Setter_Column_DoesNot_Belong_ToTable_Exception() 30 | { 31 | var column = new CsvDataColumn(); 32 | Assert.Throws(() => _row[column] = new TestData()); 33 | } 34 | 35 | [Test] 36 | public void Indexer_Getter_Column_Belongs_ToTable_ReturnsValue() 37 | { 38 | var column = new CsvDataColumn(); 39 | _table.Columns.Add(column); 40 | 41 | Assert.Null(_row[column]); 42 | } 43 | 44 | [Test] 45 | public void Indexer_Setter_Column_Belongs_ToTable_ValueSet() 46 | { 47 | var column = new CsvDataColumn(); 48 | _table.Columns.Add(column); 49 | 50 | var value = new TestData(); 51 | 52 | _row[column] = value; 53 | Assert.NotNull(_row[column]); 54 | Assert.AreSame(value, _row[column]); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tests/Csv/CsvDataTableCollectionTests.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Csv; 2 | using CoCSharp.Data.Models; 3 | using NUnit.Framework; 4 | using System; 5 | 6 | namespace CoCSharp.Test.Csv 7 | { 8 | [TestFixture] 9 | public class CsvDataTableCollectionTests 10 | { 11 | private CsvDataTableCollection _table; 12 | 13 | [SetUp] 14 | public void SetUp() 15 | { 16 | _table = new CsvDataTableCollection(); 17 | } 18 | 19 | [Test] 20 | public void Add_Null_Exception() 21 | { 22 | Assert.Throws(() => _table.Add(null)); 23 | } 24 | 25 | [Test] 26 | public void Add_ValidItem_Added() 27 | { 28 | _table.Add(new CsvDataTable()); 29 | Assert.AreEqual(1, _table.Count); 30 | } 31 | 32 | [Test] 33 | public void GetTableT_ValidItem_ReturnsSameInstance() 34 | { 35 | var row1 = new CsvDataTable(); 36 | _table.Add(row1); 37 | 38 | var retRow1 = _table.GetTable(); 39 | Assert.AreSame(row1, retRow1); 40 | } 41 | 42 | [Test] 43 | public void GetTable_InvalidArgs_Exception() 44 | { 45 | var row1 = new CsvDataTable(); 46 | _table.Add(row1); 47 | 48 | Assert.Throws(() => _table.GetTable(null)); 49 | Assert.Throws(() => _table.GetTable(typeof(object))); 50 | Assert.Throws(() => _table.GetTable(typeof(CsvData))); 51 | } 52 | 53 | [Test] 54 | public void GetTable_ValidItem_ReturnsSameInstance() 55 | { 56 | var row1 = new CsvDataTable(); 57 | _table.Add(row1); 58 | 59 | var retRow1 = _table.GetTable(typeof(ObstacleData)); 60 | Assert.AreSame(row1, retRow1); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/Csv/CsvDataTableTests.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Csv; 2 | using CoCSharp.Data.Models; 3 | using NUnit.Framework; 4 | 5 | namespace CoCSharp.Test.Csv 6 | { 7 | [TestFixture] 8 | public class CsvDataTableTests 9 | { 10 | private CsvDataTable _table; 11 | 12 | [SetUp] 13 | public void SetUp() 14 | { 15 | _table = new CsvDataTable(); 16 | } 17 | 18 | [Test] 19 | public void Rows_And_Column_Are_GenericTypes() 20 | { 21 | var castedTable = (CsvDataTable)_table; 22 | //Assert.IsAssignableFrom(typeof(CsvDataColumnCollection), castedTable.Columns); 23 | Assert.IsAssignableFrom(typeof(CsvDataRowCollection), castedTable.Rows); 24 | } 25 | 26 | [Test] 27 | public void NewRow_Table_Name_Set() 28 | { 29 | var row = _table.NewRow("test"); 30 | 31 | var actualTable = row.Table; 32 | var actualName = row.Name; 33 | 34 | Assert.AreSame(_table, actualTable); 35 | Assert.AreEqual("test", actualName); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/Csv/CsvTableTests.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Csv; 2 | using NUnit.Framework; 3 | using System; 4 | using System.IO; 5 | 6 | namespace CoCSharp.Test.Csv 7 | { 8 | [TestFixture] 9 | public class CsvTableTests 10 | { 11 | // Tests if compression are equal to original ones. 12 | [Test] 13 | public void Compression_Equality() 14 | { 15 | var tablePath = Path.Combine(TestUtils.CsvDirectory, "com_buildings.csv"); 16 | var originalbytes = File.ReadAllBytes(tablePath); 17 | 18 | // Decompress the original bytes. 19 | var deBytes = CsvTable.Decompress(originalbytes); 20 | 21 | // Compresses the decompressed bytes. 22 | var coBytes = CsvTable.Compress(deBytes); 23 | 24 | // Check if compressed/produced bytes are equal to original compressed bytes. 25 | Assert.AreEqual(originalbytes, coBytes); 26 | 27 | // Decompress the compressed bytes. 28 | var newDeBytes = CsvTable.Decompress(coBytes); 29 | 30 | // Check if decompressed/produced bytes are equal to original decompressed bytes. 31 | Assert.AreEqual(deBytes, newDeBytes); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/Csv/TestData.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Csv; 2 | 3 | namespace CoCSharp.Test.Csv 4 | { 5 | // Test CsvData. 6 | public class TestData : CsvData 7 | { 8 | internal override int KindId 9 | { 10 | get 11 | { 12 | return 420; 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/Data/AssetDownloaderTests.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Data; 2 | using NUnit.Framework; 3 | using System; 4 | 5 | namespace CoCSharp.Test.Data 6 | { 7 | [TestFixture] 8 | public class AssetDownloaderTests 9 | { 10 | // Tests the constructors for invalid arguments. 11 | [Test] 12 | public void Constructors_InvalidArgs_Exception() 13 | { 14 | Assert.Throws(() => new AssetDownloader(null)); 15 | Assert.Throws(() => new AssetDownloader("")); 16 | Assert.Throws(() => new AssetDownloader("invalidhex-string")); 17 | 18 | Assert.Throws(() => new AssetDownloader("3a4d26e5d18f907db2a82a0f808e0cced9f25dfd", null)); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/Data/AssetProviders/CsvDataTableAssetProviderTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace CoCSharp.Test.Data.AssetProviders 4 | { 5 | [TestFixture] 6 | public class CsvDataTableAssetProviderTests 7 | { 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/Logic/BuildingTests.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Data; 2 | using CoCSharp.Logic; 3 | using NUnit.Framework; 4 | using System.IO; 5 | 6 | namespace CoCSharp.Test.Logic 7 | { 8 | [TestFixture] 9 | public class BuildingTests 10 | { 11 | private Village _village; 12 | private readonly AssetManager _assets; 13 | public BuildingTests() 14 | { 15 | _assets = new AssetManager(TestUtils.CsvDirectory); 16 | AssetManager.Default = _assets; 17 | } 18 | 19 | [SetUp] 20 | public void SetUp() 21 | { 22 | _village = new Village(); 23 | } 24 | 25 | public static string Load(string name) 26 | { 27 | return File.ReadAllText(Path.Combine(TestUtils.LayoutDirectory, name + ".json")); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/Logic/LevelTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace CoCSharp.Test.Logic 4 | { 5 | [TestFixture] 6 | public class LevelTests 7 | { 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/Logic/TickTimerTests.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Logic; 2 | using NUnit.Framework; 3 | using System; 4 | 5 | namespace CoCSharp.Test.Logic 6 | { 7 | [TestFixture] 8 | public class TickTimerTests 9 | { 10 | [SetUp] 11 | public void SetUp() 12 | { 13 | _timer = new TickTimer(); 14 | } 15 | 16 | public TickTimer _timer; 17 | 18 | [Test] 19 | public void Start_NegativeArgs_Exception() 20 | { 21 | Assert.Throws(() => _timer.Start(DateTime.Now, -1, 0)); 22 | Assert.Throws(() => _timer.Start(DateTime.Now, 0, -1)); 23 | Assert.Throws(() => _timer.Start(DateTime.Now, -1, -1)); 24 | } 25 | 26 | [Test] 27 | public void Tick_() 28 | { 29 | _timer.Start(DateTime.UtcNow, 0, 10); 30 | 31 | var k = TimeUtils.ToTick(10); 32 | _timer.Tick(k); 33 | Assert.False(_timer.IsActive); 34 | Assert.True(_timer.IsComplete); 35 | Assert.AreEqual(0.0, _timer.Duration); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/Network/BufferStreamTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace CoCSharp.Test.Network 4 | { 5 | [TestFixture] 6 | public class BufferStreamTests 7 | { 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/Network/MessageBufferManagerTests.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Network; 2 | using NUnit.Framework; 3 | using System; 4 | using System.Net.Sockets; 5 | 6 | namespace CoCSharp.Test.Network 7 | { 8 | [TestFixture] 9 | public class MessageBufferManagerTests 10 | { 11 | [Test] 12 | public void Constructors_InvalidArgs() 13 | { 14 | var receiveCountEx = Assert.Throws(() => new MessageBufferManager(0, 1, 1)); 15 | Assert.That(receiveCountEx.ParamName == "receiveCount"); 16 | 17 | var sendCountEx = Assert.Throws(() => new MessageBufferManager(1, 0, 1)); 18 | Assert.That(sendCountEx.ParamName == "sendCount"); 19 | 20 | var bufferSizeEx = Assert.Throws(() => new MessageBufferManager(1, 1, 0)); 21 | Assert.That(bufferSizeEx.ParamName == "bufferSize"); 22 | } 23 | 24 | [Test] 25 | public void SetBuffer_ExceedingBufferSize_Exception() 26 | { 27 | var bufferManager = new MessageBufferManager(64, 64, 65535); 28 | for (int i = 0; i < 128; i++) 29 | { 30 | var args = new SocketAsyncEventArgs(); 31 | bufferManager.SetBuffer(args); 32 | } 33 | 34 | // We completely used the buffer therefore buffer index == buffer length. 35 | Assert.AreEqual(bufferManager.BufferIndex, 128 * 65535); 36 | 37 | Assert.Throws(() => bufferManager.SetBuffer(new SocketAsyncEventArgs())); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/Network/MessageReaderTests.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Network; 2 | using NUnit.Framework; 3 | using System; 4 | using System.IO; 5 | 6 | namespace CoCSharp.Test.Network 7 | { 8 | [TestFixture] 9 | public class MessageReaderTests 10 | { 11 | [Test] 12 | public void Constructors_InvalidArgs() 13 | { 14 | Assert.Throws(() => new MessageReader(null)); 15 | } 16 | 17 | [Test] 18 | public void Reading_Disposed_Exception() 19 | { 20 | var memstream = new MemoryStream(); 21 | var reader = new MessageReader(memstream); 22 | 23 | // Check that the BaseStream is opened. 24 | Assert.That(memstream.CanRead == true); 25 | 26 | reader.Dispose(); 27 | 28 | // Check that the BaseStream is closed. 29 | Assert.That(memstream.CanRead == false); 30 | 31 | Assert.Throws(() => reader.ReadBoolean()); 32 | 33 | Assert.Throws(() => reader.ReadInt16()); 34 | Assert.Throws(() => reader.ReadUInt16()); 35 | 36 | Assert.Throws(() => reader.ReadInt32()); 37 | Assert.Throws(() => reader.ReadUInt32()); 38 | 39 | Assert.Throws(() => reader.ReadSingle()); 40 | 41 | Assert.Throws(() => reader.ReadInt64()); 42 | Assert.Throws(() => reader.ReadUInt64()); 43 | 44 | 45 | Assert.Throws(() => reader.ReadDecimal()); 46 | Assert.Throws(() => reader.ReadDouble()); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tests/Network/MessageTests.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Network; 2 | using CoCSharp.Network.Messages; 3 | using NUnit.Framework; 4 | 5 | namespace CoCSharp.Test.Network 6 | { 7 | [TestFixture] 8 | public class MessageTests 9 | { 10 | [Test] 11 | public void GetMessageDirection_() 12 | { 13 | // NOTE: Test of Message.GetMessageDirection(Message). 14 | // LoginRequestMessage is sent by the client to the server. 15 | var directionServer = Message.GetMessageDirection(new KeepAliveRequestMessage()); 16 | Assert.AreEqual(MessageDirection.Server, directionServer); 17 | 18 | // LoginSuccessMessage is sent by the client to the client. 19 | var directionClient = Message.GetMessageDirection(new KeepAliveResponseMessage()); 20 | Assert.AreEqual(MessageDirection.Client, directionClient); 21 | 22 | 23 | 24 | 25 | 26 | // NOTE: Test of Message.GetMessageDirection(). 27 | // LoginRequestMessage is sent by the client to the server. 28 | var directionServer2 = Message.GetMessageDirection(); 29 | Assert.AreEqual(MessageDirection.Server, directionServer2); 30 | 31 | // LoginSuccessMessage is sent by the client to the client. 32 | var directionClient2 = Message.GetMessageDirection(); 33 | Assert.AreEqual(MessageDirection.Client, directionClient2); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Network/MessageWriterTests.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Network; 2 | using NUnit.Framework; 3 | using System; 4 | using System.IO; 5 | 6 | namespace CoCSharp.Test.Network 7 | { 8 | [TestFixture] 9 | public class MessageWriterTests 10 | { 11 | [Test] 12 | public void Constructors_InvalidArgs() 13 | { 14 | Assert.Throws(() => new MessageWriter(null)); 15 | } 16 | 17 | [Test] 18 | public void Writing_Disposed_Exception() 19 | { 20 | var memstream = new MemoryStream(); 21 | var writer = new MessageWriter(memstream); 22 | 23 | // Check that the BaseStream is opened. 24 | Assert.That(memstream.CanRead == true); 25 | 26 | writer.Dispose(); 27 | 28 | // Check that the BaseStream is closed. 29 | Assert.That(memstream.CanRead == false); 30 | 31 | Assert.Throws(() => writer.Write(false)); 32 | 33 | Assert.Throws(() => writer.Write((ushort)1)); 34 | Assert.Throws(() => writer.Write((short)1)); 35 | 36 | Assert.Throws(() => writer.Write((uint)1)); 37 | Assert.Throws(() => writer.Write((int)1)); 38 | 39 | Assert.Throws(() => writer.Write((float)1)); 40 | 41 | Assert.Throws(() => writer.Write((ulong)1)); 42 | Assert.Throws(() => writer.Write((long)1)); 43 | 44 | Assert.Throws(() => writer.Write((double)1)); 45 | Assert.Throws(() => writer.Write((decimal)1)); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tests/Network/Messages/Commands/BuyResourcesCommandTests.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Logic; 2 | using CoCSharp.Logic.Commands; 3 | using CoCSharp.Network; 4 | using NUnit.Framework; 5 | using System.IO; 6 | 7 | namespace CoCSharp.Test.Network.Messages.Commands 8 | { 9 | [TestFixture] 10 | public class BuyResourcesCommandTests 11 | { 12 | [Test] 13 | public void TestBuyResourcesCommandDepth() 14 | { 15 | var command = CreateCommand(5000); 16 | 17 | var commandBytes = (byte[])null; 18 | using (var writer = new MessageWriter(new MemoryStream())) 19 | { 20 | command.WriteCommand(writer); 21 | commandBytes = ((MemoryStream)writer.BaseStream).ToArray(); 22 | } 23 | 24 | var rCommand = new BuyResourcesCommand(); 25 | using (var reader = new MessageReader(new MemoryStream(commandBytes))) 26 | { 27 | Assert.Throws(() => rCommand.ReadCommand(reader)); 28 | } 29 | } 30 | 31 | public BuyResourcesCommand CreateCommand(int depth) 32 | { 33 | if (depth == 0) 34 | return null; 35 | 36 | depth--; 37 | if (depth != 0) 38 | { 39 | return new BuyResourcesCommand() 40 | { 41 | EmbedCommand = true, 42 | Command = CreateCommand(depth) 43 | }; 44 | } 45 | else 46 | { 47 | return new BuyResourcesCommand() 48 | { 49 | EmbedCommand = false, 50 | Command = null 51 | }; 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/Network/SocketAsyncEventArgsPoolTests.cs: -------------------------------------------------------------------------------- 1 | using CoCSharp.Network; 2 | using NUnit.Framework; 3 | using System; 4 | using System.Net.Sockets; 5 | 6 | namespace CoCSharp.Test.Network 7 | { 8 | [TestFixture] 9 | public class SocketAsyncEventArgsPoolTests 10 | { 11 | [Test] 12 | public void Constructors_InvalidArgs_Exception() 13 | { 14 | Assert.Throws(() => new SocketAsyncEventArgsPool(-1)); 15 | } 16 | 17 | [Test] 18 | public void PopPush_Disposed_Exception() 19 | { 20 | var pool = new SocketAsyncEventArgsPool(64); 21 | 22 | // Populate the pool. 23 | for (int i = 0; i < 64; i++) 24 | pool.Push(new SocketAsyncEventArgs()); 25 | 26 | // Remove a couple of the args. 27 | for (int i = 0; i < 32; i++) 28 | pool.Pop(); 29 | 30 | pool.Dispose(); 31 | 32 | Assert.Throws(() => pool.Push(new SocketAsyncEventArgs())); 33 | Assert.Throws(() => pool.Pop()); 34 | } 35 | 36 | [Test] 37 | public void Pop_PoolEmpty_RetusnNull() 38 | { 39 | var pool = new SocketAsyncEventArgsPool(1); 40 | var args = pool.Pop(); 41 | Assert.Null(args); 42 | } 43 | 44 | [Test] 45 | public void Push__ExceedCapacity__Pushed_And_CapacityResized() 46 | { 47 | var pool = new SocketAsyncEventArgsPool(1); 48 | var args = new SocketAsyncEventArgs(); 49 | 50 | pool.Push(args); 51 | Assert.AreEqual(1, pool.Capacity); 52 | 53 | pool.Push(args); 54 | Assert.AreEqual(2, pool.Capacity); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CoCSharp.Test")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CoCSharp.Test")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("a10e17e7-2b42-4a02-900b-b91e3950f80c")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /tests/TestUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace CoCSharp.Test 5 | { 6 | public static class TestUtils 7 | { 8 | public static readonly Random Random = new Random(); 9 | 10 | private static readonly string _baseDirectory = AppDomain.CurrentDomain.BaseDirectory; 11 | 12 | private static readonly string _contentDirectory = Path.Combine(_baseDirectory, "contents"); 13 | public static string ContentDirectory { get { return _contentDirectory; } } 14 | 15 | private static readonly string _csvDirectory = Path.Combine(_contentDirectory, "csv"); 16 | public static string CsvDirectory { get { return _csvDirectory; } } 17 | 18 | private static readonly string _layoutDirectory = Path.Combine(_contentDirectory, "layouts"); 19 | public static string LayoutDirectory { get { return _layoutDirectory; } } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/TokenUtilsTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace CoCSharp.Test 4 | { 5 | [TestFixture] 6 | public class TokenUtilsTests 7 | { 8 | [Test] 9 | public void TestTokenUtilsCheckToken() 10 | { 11 | // Invalid token length. 12 | var token1 = "someinvalidtokenlength"; 13 | Assert.False(TokenUtils.CheckToken(token1)); 14 | 15 | // Invalid character in token. 16 | var token3 = "a4knrehaamcwt6cwafenamtaxx2nye2z8pmdt9c@"; 17 | Assert.False(TokenUtils.CheckToken(token3)); 18 | 19 | // Valid token. 20 | var token2 = "a4knrehaamcwt6cwafenamtaxx2nye2z8pmdt9cx"; 21 | Assert.True(TokenUtils.CheckToken(token2)); 22 | } 23 | 24 | [Test] 25 | public void TestTokenUtilsGenerateToken() 26 | { 27 | var token = TokenUtils.GenerateToken(); 28 | Assert.True(TokenUtils.CheckToken(token)); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/contents/csv/com_buildings.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FICTURE7/CoCSharp/d8602264fd185a9236197502eb40aa57019bf4be/tests/contents/csv/com_buildings.csv -------------------------------------------------------------------------------- /tests/contents/csv/resources.csv: -------------------------------------------------------------------------------- 1 | "Name","TID","SWF","CollectEffect","ResourceIconExportName","StealEffect","PremiumCurrency","HudInstanceName","CapFullTID","TextRed","TextGreen","TextBlue","WarRefResource" 2 | "String","String","String","String","String","String","Boolean","String","String","int","int","int","String" 3 | "Diamonds","TID_DIAMONDS","sc/ui.sc","Collect Diamonds",,,"true","diamond_bar",,0,255,92, 4 | "Gold","TID_GOLD","sc/ui.sc","Collect Gold","building_resources_gold","Steal Gold",,"gold_bar","TID_RESOURCE_CAP_FULL_GOLD",240,240,0, 5 | "Elixir","TID_ELIXIR","sc/ui.sc","Collect Elixir","building_resources_elixir","Steal Elixir",,"elixir_bar","TID_RESOURCE_CAP_FULL_ELIXIR",192,0,192, 6 | "DarkElixir","TID_DARK_ELIXIR","sc/ui.sc","Collect Dark Elixir","building_resources_dark_elixir","Steal Dark Elixir",,"dark_elixir_bar","TID_RESOURCE_CAP_FULL_DARK_ELIXIR",240,240,240, 7 | "WarGold","TID_WAR_GOLD","sc/ui.sc","Collect Gold","building_resources_gold",,,,,240,240,0,"Gold" 8 | "WarElixir","TID_WAR_ELIXIR","sc/ui.sc","Collect Elixir","building_resources_elixir",,,,,192,0,192,"Elixir" 9 | "WarDarkElixir","TID_WAR_DARK_ELIXIR","sc/ui.sc","Collect Dark Elixir","building_resources_dark_elixir",,,,,240,240,240,"DarkElixir" 10 | -------------------------------------------------------------------------------- /tests/contents/layouts/buildings/no_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "buildings": 3 | [ 4 | { 5 | //"data": 1000000, No data ID should throw. 6 | "lvl": 1, 7 | "x": 1, 8 | "y": 2 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/contents/layouts/buildings/no_lvl.json: -------------------------------------------------------------------------------- 1 | { 2 | "buildings": 3 | [ 4 | { 5 | "data": 1000000, 6 | //"lvl": 1, -> No lvl should throw. 7 | "x": 1, 8 | "y": 2 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/contents/layouts/buildings/no_x.json: -------------------------------------------------------------------------------- 1 | { 2 | "buildings": 3 | [ 4 | { 5 | "data": 1000000, 6 | "lvl": 1, 7 | //"x": 1, -> No x should throw. 8 | "y": 2 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/contents/layouts/buildings/no_y.json: -------------------------------------------------------------------------------- 1 | { 2 | "buildings": 3 | [ 4 | { 5 | "data": 1000000, 6 | "lvl": 1, 7 | "x": 1, 8 | //"y": 2 -> No y should throw. 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/contents/layouts/exp_ver.json: -------------------------------------------------------------------------------- 1 | { 2 | "exp_ver": 2, 3 | "buildings": 4 | [ 5 | { 6 | "data": 1000001, // Town Hall to prevent throwing of no town hall stuff. 7 | "lvl": 1 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /tests/contents/layouts/no_townhall.json: -------------------------------------------------------------------------------- 1 | { 2 | "buildings": 3 | [ 4 | { 5 | "data": 1000000, // <- not TownHall should throw. 6 | "lvl": 1 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tests/contents/layouts/village_buildings1.json: -------------------------------------------------------------------------------- 1 | { 2 | "buildings": 3 | [ 4 | { 5 | "id": 500000000, 6 | "data": 1000001, 7 | "lvl": 2 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /tests/contents/layouts/village_buildings2.json: -------------------------------------------------------------------------------- 1 | { 2 | "buildings": 3 | [ 4 | { 5 | "data": 1000001, 6 | "id": 500000000, 7 | "lvl": 1, 8 | "x": 24, 9 | "y": 23 10 | }, 11 | { 12 | "data": 1000004, 13 | "id": 500000001, 14 | "lvl": 0, 15 | "x": 23, 16 | "y": 19 17 | }, 18 | { 19 | "data": 1000003, 20 | "id": 500000002, 21 | "lvl": -1, 22 | "x": 3, 23 | "y": 14 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | --------------------------------------------------------------------------------