Changeset 455


Ignore:
Timestamp:
Jul 31, 2023, 4:06:13 PM (17 months ago)
Author:
alloc
Message:

25_30_44

  • Got rid (mostly) of custom JSON serialization
  • Some code cleanup
Location:
binary-improvements
Files:
1 added
5 deleted
43 edited

Legend:

Unmodified
Added
Removed
  • binary-improvements/7dtd-server-fixes/7dtd-server-fixes.csproj

    r450 r455  
    8383  <ItemGroup>
    8484    <Compile Include="src\AssemblyInfo.cs" />
    85     <Compile Include="src\JSON\JsonManualBuilder.cs" />
    8685    <Compile Include="src\LiveData\Animals.cs" />
    8786    <Compile Include="src\LiveData\Hostiles.cs" />
     
    9190    <Compile Include="src\PersistentData\Players.cs" />
    9291    <Compile Include="src\PersistentData\Player.cs" />
    93     <Compile Include="src\JSON\JSONNode.cs" />
    94     <Compile Include="src\JSON\JSONArray.cs" />
    95     <Compile Include="src\JSON\JSONObject.cs" />
    96     <Compile Include="src\JSON\JSONNumber.cs" />
    97     <Compile Include="src\JSON\JSONString.cs" />
    98     <Compile Include="src\JSON\JSONBoolean.cs" />
    99     <Compile Include="src\BlockingQueue.cs" />
    100     <Compile Include="src\JSON\Parser.cs" />
    101     <Compile Include="src\JSON\JSONNull.cs" />
    102     <Compile Include="src\JSON\MalformedJSONException.cs" />
    10392    <Compile Include="src\API.cs" />
    10493    <Compile Include="src\AllocsUtils.cs" />
    10594    <Compile Include="src\LandClaimList.cs" />
    10695    <Compile Include="src\PersistentData\Attributes.cs" />
    107     <Compile Include="src\JSON\JSONValue.cs" />
    10896    <Compile Include="src\LiveData\EntityFilterList.cs" />
    10997  </ItemGroup>
     
    112100    <Folder Include="src\" />
    113101    <Folder Include="src\PersistentData\" />
    114     <Folder Include="src\JSON\Parser\" />
    115102  </ItemGroup>
    116103  <ItemGroup>
  • binary-improvements/7dtd-server-fixes/ModInfo.xml

    r448 r455  
    55                <Description value="Common functions" />
    66                <Author value="Christian 'Alloc' Illy" />
    7                 <Version value="29" />
    8                 <Website value="http://7dtd.illy.bz" />
     7                <Version value="30" />
     8                <Website value="https://7dtd.illy.bz" />
    99        </ModInfo>
    1010</xml>
  • binary-improvements/7dtd-server-fixes/src/API.cs

    r446 r455  
    11using System.Collections.Generic;
    22using AllocsFixes.PersistentData;
     3using JetBrains.Annotations;
    34using Platform.Steam;
    45
    56namespace AllocsFixes {
     7        [UsedImplicitly]
    68        public class API : IModApi {
    79                public void InitMod (Mod _modInstance) {
    810                        ModEvents.GameStartDone.RegisterHandler (GameAwake);
    9                         ModEvents.GameShutdown.RegisterHandler (GameShutdown);
    1011                        ModEvents.SavePlayerData.RegisterHandler (SavePlayerData);
    1112                        ModEvents.PlayerSpawning.RegisterHandler (PlayerSpawning);
     
    1516                }
    1617
    17                 public void GameAwake () {
     18                private static void GameAwake () {
    1819                        PersistentContainer.Load ();
    1920                }
    2021
    21                 public void GameShutdown () {
    22                 }
    23 
    24                 public void SavePlayerData (ClientInfo _cInfo, PlayerDataFile _playerDataFile) {
     22                private static void SavePlayerData (ClientInfo _cInfo, PlayerDataFile _playerDataFile) {
    2523                        PersistentContainer.Instance.Players.GetOrCreate (_cInfo.InternalId, _cInfo.PlatformId, _cInfo.CrossplatformId).Update (_cInfo, _playerDataFile);
    2624                }
    2725
    28                 public void PlayerSpawning (ClientInfo _cInfo, int _chunkViewDim, PlayerProfile _playerProfile) {
     26                private static void PlayerSpawning (ClientInfo _cInfo, int _chunkViewDim, PlayerProfile _playerProfile) {
    2927                        string owner = null;
    3028                        if (_cInfo.PlatformId is UserIdentifierSteam identifierSteam) {
     
    3230                        }
    3331
    34                         Log.Out ("Player connected" +
    35                                  ", entityid=" + _cInfo.entityId +
    36                                  ", name=" + _cInfo.playerName +
    37                                  ", pltfmid=" + (_cInfo.PlatformId?.CombinedString ?? "<unknown>") +
    38                                  ", crossid=" + (_cInfo.CrossplatformId?.CombinedString ?? "<unknown/none>") +
    39                                  ", steamOwner=" + (owner ?? "<unknown/none>") +
    40                                  ", ip=" + _cInfo.ip
     32                        Log.Out (
     33                                $"Player connected, entityid={_cInfo.entityId}, name={_cInfo.playerName}, pltfmid={_cInfo.PlatformId?.CombinedString ?? "<unknown>"}, crossid={_cInfo.CrossplatformId?.CombinedString ?? "<unknown/none>"}, steamOwner={owner ?? "<unknown/none>"}, ip={_cInfo.ip}"
    4134                        );
    4235                }
    4336
    44                 public void PlayerDisconnected (ClientInfo _cInfo, bool _bShutdown) {
     37                private static void PlayerDisconnected (ClientInfo _cInfo, bool _bShutdown) {
    4538                        Player p = PersistentContainer.Instance.Players.GetByInternalId (_cInfo.InternalId);
    4639                        if (p != null) {
     
    5346                }
    5447
    55                 public void PlayerSpawned (ClientInfo _cInfo, RespawnType _respawnReason, Vector3i _spawnPos) {
     48                private static void PlayerSpawned (ClientInfo _cInfo, RespawnType _respawnReason, Vector3i _spawnPos) {
    5649                        PersistentContainer.Instance.Players.GetOrCreate (_cInfo.InternalId, _cInfo.PlatformId, _cInfo.CrossplatformId).SetOnline (_cInfo);
    5750                        PersistentContainer.Instance.Save ();
    5851                }
    5952
    60                 private const string ANSWER =
    61                         "     [ff0000]I[-] [ff7f00]W[-][ffff00]A[-][80ff00]S[-] [00ffff]H[-][0080ff]E[-][0000ff]R[-][8b00ff]E[-]";
     53                private const string ANSWER = "     [ff0000]I[-] [ff7f00]W[-][ffff00]A[-][80ff00]S[-] [00ffff]H[-][0080ff]E[-][0000ff]R[-][8b00ff]E[-]";
    6254
    63                 public bool ChatMessage (ClientInfo _cInfo, EChatType _type, int _senderId, string _msg, string _mainName,
     55                private static bool ChatMessage (ClientInfo _cInfo, EChatType _type, int _senderId, string _msg, string _mainName,
    6456                        bool _localizeMain, List<int> _recipientEntityIds) {
    6557                        if (string.IsNullOrEmpty (_msg) || !_msg.EqualsCaseInsensitive ("/alloc")) {
     
    6860
    6961                        if (_cInfo != null) {
    70                                 Log.Out ("Sent chat hook reply to {0}", _cInfo.InternalId);
     62                                Log.Out ($"Sent chat hook reply to {_cInfo.InternalId}");
    7163                                _cInfo.SendPackage (NetPackageManager.GetPackage<NetPackageChat> ().Setup (EChatType.Whisper, -1, ANSWER, "", false, null));
    7264                        } else {
    73                                 Log.Error ("ChatHookExample: Argument _cInfo null on message: {0}", _msg);
     65                                Log.Error ($"ChatHookExample: Argument _cInfo null on message: {_msg}");
    7466                        }
    7567
  • binary-improvements/7dtd-server-fixes/src/AllocsUtils.cs

    r325 r455  
    44        public static class AllocsUtils {
    55                public static string ColorToHex (Color _color) {
    6                         return string.Format ("{0:X02}{1:X02}{2:X02}", (int) (_color.r * 255), (int) (_color.g * 255),
    7                                 (int) (_color.b * 255));
     6                        return $"{(int)(_color.r * 255):X02}{(int)(_color.g * 255):X02}{(int)(_color.b * 255):X02}";
    87                }
    98        }
  • binary-improvements/7dtd-server-fixes/src/PersistentData/Attributes.cs

    r326 r455  
    88
    99                public bool HideChatCommands {
    10                         get { return hideChatCommands; }
    11                         set { hideChatCommands = value; }
     10                        get => hideChatCommands;
     11                        set => hideChatCommands = value;
    1212                }
    1313
    1414                public string HideChatCommandPrefix {
    15                         get {
    16                                 if (hideChatCommandPrefix == null) {
    17                                         hideChatCommandPrefix = "";
    18                                 }
    19 
    20                                 return hideChatCommandPrefix;
    21                         }
    22                         set { hideChatCommandPrefix = value; }
     15                        get => hideChatCommandPrefix ??= "";
     16                        set => hideChatCommandPrefix = value;
    2317                }
    2418        }
  • binary-improvements/7dtd-server-fixes/src/PersistentData/Inventory.cs

    r351 r455  
    2424                }
    2525
    26                 private void ProcessInv (List<InvItem> _target, ItemStack[] _sourceFields, int _id) {
     26                private void ProcessInv (ICollection<InvItem> _target, IReadOnlyList<ItemStack> _sourceFields, int _id) {
    2727                        _target.Clear ();
    28                         for (int i = 0; i < _sourceFields.Length; i++) {
     28                        for (int i = 0; i < _sourceFields.Count; i++) {
    2929                                InvItem item = CreateInvItem (_sourceFields [i].itemValue, _sourceFields [i].count, _id);
    3030                                if (item != null && _sourceFields [i].itemValue.Modifications != null) {
     
    4343                }
    4444
    45                 private void ProcessParts (ItemValue[] _parts, InvItem _item, int _playerId) {
    46                         InvItem[] itemParts = new InvItem[_parts.Length];
    47                         for (int i = 0; i < _parts.Length; i++) {
     45                private void ProcessParts (IReadOnlyList<ItemValue> _parts, InvItem _item, int _playerId) {
     46                        InvItem[] itemParts = new InvItem[_parts.Count];
     47                        for (int i = 0; i < _parts.Count; i++) {
    4848                                InvItem partItem = CreateInvItem (_parts [i], 1, _playerId);
    4949                                if (partItem != null && _parts [i].Modifications != null) {
     
    6767
    6868                        if (_count > maxAllowed) {
    69                                 Log.Out ("Player with ID " + _playerId + " has stack for \"" + name + "\" greater than allowed (" +
    70                                          _count + " > " + maxAllowed + ")");
     69                                Log.Out ($"Player with ID {_playerId} has stack for \"{name}\" greater than allowed ({_count} > {maxAllowed})");
    7170                        }
    7271
  • binary-improvements/7dtd-server-fixes/src/PersistentData/PersistentContainer.cs

    r448 r455  
    1212                [OptionalField] private Attributes attributes;
    1313
    14                 public Players Players {
    15                         get {
    16                                 if (players == null) {
    17                                         players = new Players ();
    18                                 }
     14                public Players Players => players ??= new Players ();
    1915
    20                                 return players;
    21                         }
    22                 }
    23 
    24                 public Attributes Attributes {
    25                         get {
    26                                 if (attributes == null) {
    27                                         attributes = new Attributes ();
    28                                 }
    29 
    30                                 return attributes;
    31                         }
    32                 }
     16                public Attributes Attributes => attributes ??= new Attributes ();
    3317
    3418                private static PersistentContainer instance;
    3519
    36                 public static PersistentContainer Instance {
    37                         get {
    38                                 if (instance == null) {
    39                                         instance = new PersistentContainer ();
    40                                 }
    41 
    42                                 return instance;
    43                         }
    44                 }
     20                public static PersistentContainer Instance => instance ??= new PersistentContainer ();
    4521
    4622                private PersistentContainer () {
     
    4925                public void Save () {
    5026                        lock (fileLockObject) {
    51                                 using Stream stream = File.Open (GameIO.GetSaveGameDir () + persistentDataFileName, FileMode.Create);
     27                                using Stream stream = File.Open ($"{GameIO.GetSaveGameDir ()}{persistentDataFileName}", FileMode.Create);
    5228                                BinaryFormatter bFormatter = new BinaryFormatter ();
    5329                                bFormatter.Serialize (stream, this);
     
    5632
    5733                public static bool Load () {
    58                         if (!File.Exists (GameIO.GetSaveGameDir () + persistentDataFileName)) {
     34                        var filePath = $"{GameIO.GetSaveGameDir ()}{persistentDataFileName}";
     35                       
     36                        if (!File.Exists (filePath)) {
    5937                                return false;
    6038                        }
     
    6341                                PersistentContainer obj;
    6442                                lock (fileLockObject) {
    65                                         using Stream stream = File.Open (GameIO.GetSaveGameDir () + persistentDataFileName, FileMode.Open);
     43                                        using Stream stream = File.Open (filePath, FileMode.Open);
    6644                                        BinaryFormatter bFormatter = new BinaryFormatter ();
    6745                                        obj = (PersistentContainer)bFormatter.Deserialize (stream);
  • binary-improvements/7dtd-server-fixes/src/PersistentData/Player.cs

    r447 r455  
    124124                        }
    125125
    126                         Log.Out ("Player set to offline: " + InternalId);
     126                        Log.Out ($"Player set to offline: {InternalId}");
    127127                        lastOnline = DateTime.Now;
    128128                        try {
     
    140140
    141141                public void SetOnline (ClientInfo _ci) {
    142                         Log.Out ("Player set to online: " + InternalId);
     142                        Log.Out ($"Player set to online: {InternalId}");
    143143                        clientInfo = _ci;
    144144            entityId = _ci.entityId;
  • binary-improvements/7dtd-server-fixes/src/PersistentData/Players.cs

    r446 r455  
    1919                        }
    2020
    21                         Log.Out ("Created new player entry for ID: " + _internalId);
     21                        Log.Out ($"Created new player entry for ID: {_internalId}");
    2222                        Player p = new Player (_internalId, _platformId, _crossPlatformId);
    2323                        Dict.Add (_internalId, p);
  • binary-improvements/AllocsCommands/AllocsCommands.csproj

    r450 r455  
    6060  </ItemGroup>
    6161  <ItemGroup>
    62     <Compile Include="API.cs" />
    6362    <Compile Include="AssemblyInfo.cs" />
    6463    <Compile Include="Commands\ListKnownPlayers.cs" />
  • binary-improvements/AllocsCommands/Commands/ListKnownPlayers.cs

    r446 r455  
    11using System.Collections.Generic;
    22using AllocsFixes.PersistentData;
     3using JetBrains.Annotations;
    34
    45namespace AllocsFixes.CustomCommands {
     6        [UsedImplicitly]
    57        public class ListKnownPlayers : ConsoleCmdAbstract {
    68                protected override string getDescription () {
  • binary-improvements/AllocsCommands/Commands/ListLandProtection.cs

    r446 r455  
    22using System.Collections.Generic;
    33using AllocsFixes.PersistentData;
     4using JetBrains.Annotations;
    45
    56namespace AllocsFixes.CustomCommands {
     7        [UsedImplicitly]
    68        public class ListLandProtection : ConsoleCmdAbstract {
    79                protected override string getDescription () {
     
    5759                                                userIdFilter = ci.InternalId;
    5860                                        } else {
    59                                                 SdtdConsole.Instance.Output ("Player name or entity id \"" + _params [0] + "\" not found.");
     61                                                SdtdConsole.Instance.Output ($"Player name or entity id \"{_params[0]}\" not found.");
    6062                                                return;
    6163                                        }
     
    7981                                        } catch (Exception e) {
    8082                                                SdtdConsole.Instance.Output ("Error getting current player's position");
    81                                                 Log.Out ("Error in ListLandProtection.Run: " + e);
     83                                                Log.Out ($"Error in ListLandProtection.Run: {e}");
    8284                                                return;
    8385                                        }
     
    102104
    103105                        foreach (KeyValuePair<Player, List<Vector3i>> kvp in claims) {
    104                                 SdtdConsole.Instance.Output (string.Format (
    105                                         "Player \"{0} ({1})\" owns {4} keystones (protected: {2}, current hardness multiplier: {3})",
    106                                         kvp.Key.Name,
    107                                         kvp.Key.InternalId,
    108                                         kvp.Key.LandProtectionActive,
    109                                         kvp.Key.LandProtectionMultiplier,
    110                                         kvp.Value.Count));
    111                                 if (!summaryOnly) {
    112                                         foreach (Vector3i v in kvp.Value) {
    113                                                 if (parseableOutput) {
    114                                                         SdtdConsole.Instance.Output ("LandProtectionOf: id=" + kvp.Key.InternalId +
    115                                                                                      ", playerName=" + kvp.Key.Name + ", location=" + v);
    116                                                 } else {
    117                                                         SdtdConsole.Instance.Output ("   (" + v + ")");
    118                                                 }
     106                                SdtdConsole.Instance.Output (
     107                                        $"Player \"{kvp.Key.Name} ({kvp.Key.InternalId})\" owns {kvp.Value.Count} keystones (protected: {kvp.Key.LandProtectionActive}, current hardness multiplier: {kvp.Key.LandProtectionMultiplier})");
     108                                if (summaryOnly) {
     109                                        continue;
     110                                }
     111
     112                                foreach (Vector3i v in kvp.Value) {
     113                                        if (parseableOutput) {
     114                                                SdtdConsole.Instance.Output ($"LandProtectionOf: id={kvp.Key.InternalId}, playerName={kvp.Key.Name}, location={v}");
     115                                        } else {
     116                                                SdtdConsole.Instance.Output ($"   ({v})");
    119117                                        }
    120118                                }
     
    122120
    123121                        if (userIdFilter == null) {
    124                                 SdtdConsole.Instance.Output ("Total of " + ppl.m_lpBlockMap.Count + " keystones in the game");
     122                                SdtdConsole.Instance.Output ($"Total of {ppl.m_lpBlockMap.Count} keystones in the game");
    125123                        }
    126124                }
  • binary-improvements/AllocsCommands/Commands/RemoveLandProtection.cs

    r420 r455  
    22using System.Collections.Generic;
    33using AllocsFixes.PersistentData;
     4using JetBrains.Annotations;
    45
    56namespace AllocsFixes.CustomCommands {
     7        [UsedImplicitly]
    68        public class RemoveLandProtection : ConsoleCmdAbstract {
    79                protected override string getDescription () {
     
    4749                                GameManager.Instance.SetBlocksRPC (changes);
    4850
    49                                 SdtdConsole.Instance.Output ("Tried to remove #" + changes.Count +
    50                                                              " land protection blocks for player \"" + _id + "\". Note " +
    51                                                              "that only blocks in chunks that are currently loaded (close to any player) could be removed. " +
    52                                                              "Please check for remaining blocks by running:");
    53                                 SdtdConsole.Instance.Output ("  listlandprotection " + _id);
     51                                SdtdConsole.Instance.Output (
     52                                        $"Tried to remove #{changes.Count} land protection blocks for player \"{_id}\". Note that only blocks in chunks that are currently loaded (close to any player) could be removed. Please check for remaining blocks by running:");
     53                                SdtdConsole.Instance.Output ($"  listlandprotection {_id}");
    5454                        } catch (Exception e) {
    55                                 Log.Out ("Error in RemoveLandProtection.removeById: " + e);
     55                                Log.Out ($"Error in RemoveLandProtection.removeById: {e}");
    5656                        }
    5757                }
    5858
    59                 private void removeByPosition (List<string> _coords) {
     59                private void removeByPosition (IReadOnlyList<string> _coords) {
    6060                        int.TryParse (_coords [0], out int x);
    6161                        int.TryParse (_coords [1], out int y);
     
    8484                        GameManager.Instance.SetBlocksRPC (changes);
    8585
    86                         SdtdConsole.Instance.Output ("Land protection block at (" + v + ") removed");
     86                        SdtdConsole.Instance.Output ($"Land protection block at ({v}) removed");
    8787                }
    8888
     
    125125                                        } catch (Exception e) {
    126126                                                SdtdConsole.Instance.Output ("Error removing claims");
    127                                                 Log.Out ("Error in RemoveLandProtection.Run: " + e);
     127                                                Log.Out ($"Error in RemoveLandProtection.Run: {e}");
    128128                                        }
    129129                                } catch (Exception e) {
    130130                                        SdtdConsole.Instance.Output ("Error getting current player's position");
    131                                         Log.Out ("Error in RemoveLandProtection.Run: " + e);
     131                                        Log.Out ($"Error in RemoveLandProtection.Run: {e}");
    132132                                }
    133133                        } else if (_params.Count == 1) {
  • binary-improvements/AllocsCommands/Commands/ShowInventory.cs

    r446 r455  
    11using System.Collections.Generic;
    22using AllocsFixes.PersistentData;
     3using JetBrains.Annotations;
    34
    45namespace AllocsFixes.CustomCommands {
     6        [UsedImplicitly]
    57        public class ShowInventory : ConsoleCmdAbstract {
    68                protected override string getDescription () {
     
    4446
    4547                        if (tag == null) {
    46                                 SdtdConsole.Instance.Output ("Belt of player " + p.Name + ":");
     48                                SdtdConsole.Instance.Output ($"Belt of player {p.Name}:");
    4749                        }
    4850
     
    5355
    5456                        if (tag == null) {
    55                                 SdtdConsole.Instance.Output ("Bagpack of player " + p.Name + ":");
     57                                SdtdConsole.Instance.Output ($"Bagpack of player {p.Name}:");
    5658                        }
    5759
     
    6264
    6365                        if (tag == null) {
    64                                 SdtdConsole.Instance.Output ("Equipment of player " + p.Name + ":");
     66                                SdtdConsole.Instance.Output ($"Equipment of player {p.Name}:");
    6567                        }
    6668
     
    6870
    6971                        if (tag != null) {
    70                                 SdtdConsole.Instance.Output ("tracker_item id=" + p.EntityID + ", tag=" + tag +
    71                                                              ", SHOWINVENTORY DONE");
     72                                SdtdConsole.Instance.Output ($"tracker_item id={p.EntityID}, tag={tag}, SHOWINVENTORY DONE");
    7273                        }
    7374                }
    7475
    75                 private void PrintInv (List<InvItem> _inv, int _entityId, string _location, string _tag) {
     76                private static void PrintInv (IReadOnlyList<InvItem> _inv, int _entityId, string _location, string _tag) {
    7677                        for (int i = 0; i < _inv.Count; i++) {
    77                                 if (_inv [i] != null) {
    78                                         if (_tag == null) {
    79                                                 // no Tag defined -> readable output
    80                                                 if (_inv [i].quality < 0) {
    81                                                         SdtdConsole.Instance.Output (string.Format ("    Slot {0}: {1:000} * {2}", i,
    82                                                                 _inv [i].count, _inv [i].itemName));
    83                                                 } else {
    84                                                         SdtdConsole.Instance.Output (string.Format ("    Slot {0}: {1:000} * {2} - quality: {3}", i,
    85                                                                 _inv [i].count, _inv [i].itemName, _inv [i].quality));
    86                                                 }
     78                                if (_inv[i] == null) {
     79                                        continue;
     80                                }
    8781
    88                                                 DoParts (_inv [i].parts, 1, null);
     82                                if (_tag == null) {
     83                                        // no Tag defined -> readable output
     84                                        if (_inv [i].quality < 0) {
     85                                                SdtdConsole.Instance.Output (string.Format ("    Slot {0}: {1:000} * {2}", i,
     86                                                        _inv [i].count, _inv [i].itemName));
    8987                                        } else {
    90                                                 // Tag defined -> parseable output
    91                                                 string partsMsg = DoParts (_inv [i].parts, 1, "");
    92                                                 string msg = "tracker_item id=" + _entityId + ", tag=" + _tag + ", location=" + _location +
    93                                                              ", slot=" + i + ", item=" + _inv [i].itemName + ", qnty=" + _inv [i].count +
    94                                                              ", quality=" + _inv [i].quality + ", parts=(" + partsMsg + ")";
    95                                                 SdtdConsole.Instance.Output (msg);
     88                                                SdtdConsole.Instance.Output (string.Format ("    Slot {0}: {1:000} * {2} - quality: {3}", i,
     89                                                        _inv [i].count, _inv [i].itemName, _inv [i].quality));
    9690                                        }
     91
     92                                        DoParts (_inv [i].parts, 1, null);
     93                                } else {
     94                                        // Tag defined -> parseable output
     95                                        string partsMsg = DoParts (_inv [i].parts, 1, "");
     96                                        string msg = "tracker_item id=" + _entityId + ", tag=" + _tag + ", location=" + _location +
     97                                                     ", slot=" + i + ", item=" + _inv [i].itemName + ", qnty=" + _inv [i].count +
     98                                                     ", quality=" + _inv [i].quality + ", parts=(" + partsMsg + ")";
     99                                        SdtdConsole.Instance.Output (msg);
    97100                                }
    98101                        }
    99102                }
    100103
    101                 private void PrintEquipment (InvItem[] _equipment, int _entityId, string _location, string _tag) {
     104                private static void PrintEquipment (IReadOnlyList<InvItem> _equipment, int _entityId, string _location, string _tag) {
    102105                        AddEquipment ("head", _equipment, EquipmentSlots.Headgear, _entityId, _location, _tag);
    103106                        AddEquipment ("eyes", _equipment, EquipmentSlots.Eyewear, _entityId, _location, _tag);
     
    115118                }
    116119
    117                 private void AddEquipment (string _slotname, InvItem[] _items, EquipmentSlots _slot, int _entityId,
     120                private static void AddEquipment (string _slotname, IReadOnlyList<InvItem> _items, EquipmentSlots _slot, int _entityId,
    118121                        string _location, string _tag) {
    119122                        int[] slotindices = XUiM_PlayerEquipment.GetSlotIndicesByEquipmentSlot (_slot);
    120123
    121124                        for (int i = 0; i < slotindices.Length; i++) {
    122                                 if (_items != null && _items [slotindices [i]] != null) {
    123                                         InvItem item = _items [slotindices [i]];
    124                                         if (_tag == null) {
    125                                                 // no Tag defined -> readable output
    126                                                 if (item.quality < 0) {
    127                                                         SdtdConsole.Instance.Output (string.Format ("    Slot {0:8}: {1:000}", _slotname,
    128                                                                 item.itemName));
    129                                                 } else {
    130                                                         SdtdConsole.Instance.Output (string.Format ("    Slot {0:8}: {1:000} - quality: {2}",
    131                                                                 _slotname, item.itemName, item.quality));
    132                                                 }
     125                                if (_items == null || _items[slotindices[i]] == null) {
     126                                        continue;
     127                                }
    133128
    134                                                 DoParts (_items [slotindices [i]].parts, 1, null);
     129                                InvItem item = _items [slotindices [i]];
     130                                if (_tag == null) {
     131                                        // no Tag defined -> readable output
     132                                        if (item.quality < 0) {
     133                                                SdtdConsole.Instance.Output (string.Format ("    Slot {0:8}: {1:000}", _slotname,
     134                                                        item.itemName));
    135135                                        } else {
    136                                                 // Tag defined -> parseable output
    137                                                 string partsMsg = DoParts (_items [slotindices [i]].parts, 1, "");
    138                                                 string msg = "tracker_item id=" + _entityId + ", tag=" + _tag + ", location=" + _location +
    139                                                              ", slot=" + _slotname + ", item=" + item.itemName + ", qnty=1, quality=" +
    140                                                              item.quality + ", parts=(" + partsMsg + ")";
    141                                                 SdtdConsole.Instance.Output (msg);
     136                                                SdtdConsole.Instance.Output (string.Format ("    Slot {0:8}: {1:000} - quality: {2}",
     137                                                        _slotname, item.itemName, item.quality));
    142138                                        }
    143139
    144                                         return;
     140                                        DoParts (_items [slotindices [i]].parts, 1, null);
     141                                } else {
     142                                        // Tag defined -> parseable output
     143                                        string partsMsg = DoParts (_items [slotindices [i]].parts, 1, "");
     144                                        string msg = $"tracker_item id={_entityId}, tag={_tag}, location={_location}, slot={_slotname}, item={item.itemName}, qnty=1, quality={item.quality}, parts=({partsMsg})";
     145                                        SdtdConsole.Instance.Output (msg);
    145146                                }
     147
     148                                return;
    146149                        }
    147150                }
    148151
    149                 private string DoParts (InvItem[] _parts, int _indent, string _currentMessage) {
    150                         if (_parts != null && _parts.Length > 0) {
    151                                 string indenter = new string (' ', _indent * 4);
    152                                 for (int i = 0; i < _parts.Length; i++) {
    153                                         if (_parts [i] != null) {
    154                                                 if (_currentMessage == null) {
    155                                                         // no currentMessage given -> readable output
    156                                                         if (_parts [i].quality < 0) {
    157                                                                 SdtdConsole.Instance.Output (string.Format ("{0}         - {1}", indenter,
    158                                                                         _parts [i].itemName));
    159                                                         } else {
    160                                                                 SdtdConsole.Instance.Output (string.Format ("{0}         - {1} - quality: {2}",
    161                                                                         indenter, _parts [i].itemName, _parts [i].quality));
    162                                                         }
     152                private static string DoParts (IReadOnlyList<InvItem> _parts, int _indent, string _currentMessage) {
     153                        if (_parts == null || _parts.Count <= 0) {
     154                                return _currentMessage;
     155                        }
    163156
    164                                                         DoParts (_parts [i].parts, _indent + 1, null);
    165                                                 } else {
    166                                                         // currentMessage given -> parseable output
    167                                                         if (_currentMessage.Length > 0) {
    168                                                                 _currentMessage += ",";
    169                                                         }
     157                        string indenter = new string (' ', _indent * 4);
     158                        for (int i = 0; i < _parts.Count; i++) {
     159                                if (_parts[i] == null) {
     160                                        continue;
     161                                }
    170162
    171                                                         _currentMessage += _parts [i].itemName + "@" + _parts [i].quality;
    172                                                         _currentMessage = DoParts (_parts [i].parts, _indent + 1, _currentMessage);
    173                                                 }
     163                                if (_currentMessage == null) {
     164                                        // no currentMessage given -> readable output
     165                                        if (_parts [i].quality < 0) {
     166                                                SdtdConsole.Instance.Output (string.Format ("{0}         - {1}", indenter,
     167                                                        _parts [i].itemName));
     168                                        } else {
     169                                                SdtdConsole.Instance.Output (string.Format ("{0}         - {1} - quality: {2}",
     170                                                        indenter, _parts [i].itemName, _parts [i].quality));
    174171                                        }
     172
     173                                        DoParts (_parts [i].parts, _indent + 1, null);
     174                                } else {
     175                                        // currentMessage given -> parseable output
     176                                        if (_currentMessage.Length > 0) {
     177                                                _currentMessage += ",";
     178                                        }
     179
     180                                        _currentMessage += $"{_parts[i].itemName}@{_parts[i].quality}";
     181                                        _currentMessage = DoParts (_parts [i].parts, _indent + 1, _currentMessage);
    175182                                }
    176183                        }
  • binary-improvements/AllocsCommands/ModInfo.xml

    r446 r455  
    55                <Description value="Additional commands for server operation" />
    66                <Author value="Christian 'Alloc' Illy" />
    7                 <Version value="24" />
    8                 <Website value="http://7dtd.illy.bz" />
     7                <Version value="25" />
     8                <Website value="https://7dtd.illy.bz" />
    99        </ModInfo>
    1010</xml>
  • binary-improvements/MapRendering/API.cs

    r454 r455  
    11using System;
    22using System.IO;
    3 using Webserver;
     3using JetBrains.Annotations;
    44using Webserver.FileCache;
    55using Webserver.UrlHandlers;
    66
    7 namespace AllocsFixes {
     7namespace AllocsFixes.Web {
     8        [UsedImplicitly]
    89        public class API : IModApi {
    9                 private Mod modInstance;
     10                private static Mod modInstance;
    1011               
    1112                public void InitMod (Mod _modInstance) {
    1213                        modInstance = _modInstance;
    1314
    14                         Web.ServerInitialized += _web => {
    15                                 try {
    16                                         const string legacyModUrl = "/legacymap";
    17                                         const string legacyFilesFoldername = "webserver_legacy";
    18                                         string legacyFilePath = $"{modInstance.Path}/{legacyFilesFoldername}";
    19                                
    20                                         if (!Directory.Exists (legacyFilePath)) {
    21                                                 Log.Out ($"Legacy webmod feature not started (folder \"{legacyFilesFoldername}\" not found in Allocs_WebAndMapRendering mod folder)");
    22                                                 return;
    23                                         }
    24 
    25                                         // TODO: Read from config
    26                                         bool useStaticCache = false;
    27 
    28                                         _web.RegisterPathHandler ("/legacymap.htm", new SimpleRedirectHandler ($"{legacyModUrl}/index.html"));
    29                                         _web.RegisterPathHandler ($"{legacyModUrl}/", new StaticHandler (legacyFilePath, useStaticCache ? (AbstractCache) new SimpleCache () : new DirectAccess (), false));
    30 
    31                                         int webPort = GamePrefs.GetInt (EnumUtils.Parse<EnumGamePrefs> (nameof (EnumGamePrefs.WebDashboardPort)));
    32                                         Log.Out ($"Started legacy webmod feature on port {webPort}, local adress {legacyModUrl}");
    33                                 } catch (Exception e) {
    34                                         Log.Out ("Error in Web.ctor: " + e);
    35                                 }
    36                         };
     15                        Webserver.Web.ServerInitialized += OnWebServerInitialized;
    3716                }
    3817
    39                 // public static void SetResponseTextContent (HttpListenerResponse _context.Response, string _text) {
    40                 //      byte[] buf = Encoding.UTF8.GetBytes (_text);
    41                 //      _context.Response.ContentLength64 = buf.Length;
    42                 //      _context.Response.ContentType = "text/html";
    43                 //      _context.Response.ContentEncoding = Encoding.UTF8;
    44                 //      _context.Response.OutputStream.Write (buf, 0, buf.Length);
    45                 // }
     18                private static void OnWebServerInitialized (Webserver.Web _web) {
     19                        try {
     20                                const string legacyModUrl = "/legacymap";
     21                                const string legacyFilesFoldername = "webserver_legacy";
     22                                string legacyFilePath = $"{modInstance.Path}/{legacyFilesFoldername}";
    4623
    47                
     24                                if (!Directory.Exists (legacyFilePath)) {
     25                                        Log.Out ($"Legacy webmod feature not started (folder \"{legacyFilesFoldername}\" not found in Allocs_WebAndMapRendering mod folder)");
     26                                        return;
     27                                }
     28
     29                                // TODO: Read from config
     30                                bool useStaticCache = false;
     31
     32                                _web.RegisterPathHandler ($"{legacyModUrl}", new SimpleRedirectHandler ($"{legacyModUrl}/index.html"));
     33                                _web.RegisterPathHandler ($"{legacyModUrl}/", new StaticHandler (legacyFilePath, useStaticCache ? new SimpleCache () : new DirectAccess (), false));
     34
     35                                int webPort = GamePrefs.GetInt (EnumUtils.Parse<EnumGamePrefs> (nameof(EnumGamePrefs.WebDashboardPort)));
     36                                Log.Out ($"Started legacy webmod feature on port {webPort}, local adress {legacyModUrl}");
     37                        } catch (Exception e) {
     38                                Log.Out ($"Error in Web.ctor: {e}");
     39                        }
     40                }
    4841        }
    4942}
  • binary-improvements/MapRendering/API/ExecuteConsoleCommand.cs

    r454 r455  
    11using System;
    22using System.Net;
     3using JetBrains.Annotations;
    34using Webserver;
    45using Webserver.WebAPI;
    5 using WebCommandResult = AllocsFixes.NetConnections.Servers.Web.WebCommandResult;
     6using WebCommandResult = AllocsFixes.Web.WebCommandResult;
    67
    78namespace AllocsFixes.WebAPIs {
     9        [UsedImplicitly]
    810        public class ExecuteConsoleCommand : AbsWebAPI {
    911                public override void HandleRequest (RequestContext _context) {
     
    1618                                _context.Request.QueryString ["raw"] != null
    1719                                        ? WebCommandResult.ResultType.Raw
    18                                         : (_context.Request.QueryString ["simple"] != null
     20                                        : _context.Request.QueryString ["simple"] != null
    1921                                                ? WebCommandResult.ResultType.ResultOnly
    20                                                 : WebCommandResult.ResultType.Full);
     22                                                : WebCommandResult.ResultType.Full;
    2123
    2224                        string commandline = _context.Request.QueryString ["command"];
  • binary-improvements/MapRendering/API/GetAllowedCommands.cs

    r454 r455  
    1 using AllocsFixes.JSON;
     1using JetBrains.Annotations;
     2using Utf8Json;
    23using Webserver;
    34using Webserver.WebAPI;
    45
    56namespace AllocsFixes.WebAPIs {
     7        [UsedImplicitly]
    68        public class GetAllowedCommands : AbsWebAPI {
     9                private static readonly byte[] jsonKeyCommands = JsonWriter.GetEncodedPropertyNameWithBeginObject ("commands");
     10
     11                private static readonly byte[] jsonKeyCommand = JsonWriter.GetEncodedPropertyNameWithBeginObject ("command");
     12                private static readonly byte[] jsonKeyDescription = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("description");
     13                private static readonly byte[] jsonKeyHelp = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("help");
     14
    715                public override void HandleRequest (RequestContext _context) {
    8                         JSONObject result = new JSONObject ();
    9                         JSONArray entries = new JSONArray ();
     16                        JsonWriter writer = new JsonWriter ();
     17                       
     18                        writer.WriteRaw (jsonKeyCommands);
     19                        writer.WriteBeginArray ();
     20
     21                        bool first = true;
     22
    1023                        foreach (IConsoleCommand cc in SdtdConsole.Instance.GetCommands ()) {
    1124                                int commandPermissionLevel = GameManager.Instance.adminTools.Commands.GetCommandPermissionLevel (cc.GetCommands ());
    12                                 if (_context.PermissionLevel <= commandPermissionLevel) {
    13                                         string cmd = string.Empty;
    14                                         foreach (string s in cc.GetCommands ()) {
    15                                                 if (s.Length > cmd.Length) {
    16                                                         cmd = s;
    17                                                 }
     25                                if (_context.PermissionLevel > commandPermissionLevel) {
     26                                        continue;
     27                                }
     28
     29                                string cmd = string.Empty;
     30                                foreach (string s in cc.GetCommands ()) {
     31                                        if (s.Length > cmd.Length) {
     32                                                cmd = s;
    1833                                        }
     34                                }
    1935
    20                                         JSONObject cmdObj = new JSONObject ();
    21                                         cmdObj.Add ("command", new JSONString (cmd));
    22                                         cmdObj.Add ("description", new JSONString (cc.GetDescription ()));
    23                                         cmdObj.Add ("help", new JSONString (cc.GetHelp ()));
    24                                         entries.Add (cmdObj);
     36                                if (!first) {
     37                                        writer.WriteValueSeparator ();
    2538                                }
     39
     40                                first = false;
     41                               
     42                                writer.WriteRaw (jsonKeyCommand);
     43                                writer.WriteString (cmd);
     44                               
     45                                writer.WriteRaw (jsonKeyDescription);
     46                                writer.WriteString (cc.GetDescription ());
     47                               
     48                                writer.WriteRaw (jsonKeyHelp);
     49                                if (cc.GetHelp () == null) {
     50                                        writer.WriteString ("");
     51                                } else {
     52                                        writer.WriteString (cc.GetHelp ());
     53                                }
     54
     55                                writer.WriteEndObject ();
    2656                        }
    2757
    28                         result.Add ("commands", entries);
    29 
    30                         LegacyApiHelper.WriteJSON (_context.Response, result);
     58                        writer.WriteEndArray ();
     59                        writer.WriteEndObject ();
     60                       
     61                        WebUtils.WriteJsonData (_context.Response, ref writer);
    3162                }
    3263
  • binary-improvements/MapRendering/API/GetAnimalsLocation.cs

    r454 r455  
    1 using System.Collections.Generic;
    2 using AllocsFixes.JSON;
    3 using AllocsFixes.LiveData;
    4 using Webserver;
    5 using Webserver.WebAPI;
     1using AllocsFixes.LiveData;
     2using JetBrains.Annotations;
    63
    74namespace AllocsFixes.WebAPIs {
    8         internal class GetAnimalsLocation : AbsWebAPI {
    9                 private readonly List<EntityAnimal> animals = new List<EntityAnimal> ();
    10 
    11                 public override void HandleRequest (RequestContext _context) {
    12                         JSONArray animalsJsResult = new JSONArray ();
    13 
    14                         Animals.Instance.Get (animals);
    15                         for (int i = 0; i < animals.Count; i++) {
    16                                 EntityAnimal entity = animals [i];
    17                                 Vector3i position = new Vector3i (entity.GetPosition ());
    18 
    19                                 JSONObject jsonPOS = new JSONObject ();
    20                                 jsonPOS.Add ("x", new JSONNumber (position.x));
    21                                 jsonPOS.Add ("y", new JSONNumber (position.y));
    22                                 jsonPOS.Add ("z", new JSONNumber (position.z));
    23 
    24                                 JSONObject pJson = new JSONObject ();
    25                                 pJson.Add ("id", new JSONNumber (entity.entityId));
    26 
    27                                 if (!string.IsNullOrEmpty (entity.EntityName)) {
    28                                         pJson.Add ("name", new JSONString (entity.EntityName));
    29                                 } else {
    30                                         pJson.Add ("name", new JSONString ("animal class #" + entity.entityClass));
    31                                 }
    32 
    33                                 pJson.Add ("position", jsonPOS);
    34 
    35                                 animalsJsResult.Add (pJson);
    36                         }
    37 
    38                         LegacyApiHelper.WriteJSON (_context.Response, animalsJsResult);
     5        [UsedImplicitly]
     6        internal class GetAnimalsLocation : GetEntityListAbs<EntityAnimal> {
     7                public GetAnimalsLocation () : base (Animals.Instance.Get) {
    398                }
    409        }
  • binary-improvements/MapRendering/API/GetHostileLocation.cs

    r454 r455  
    1 using System.Collections.Generic;
    2 using AllocsFixes.JSON;
    3 using AllocsFixes.LiveData;
    4 using Webserver;
    5 using Webserver.WebAPI;
     1using AllocsFixes.LiveData;
     2using JetBrains.Annotations;
    63
    74namespace AllocsFixes.WebAPIs {
    8         internal class GetHostileLocation : AbsWebAPI {
    9                 private readonly List<EntityEnemy> enemies = new List<EntityEnemy> ();
    10 
    11                 public override void HandleRequest (RequestContext _context) {
    12                         JSONArray hostilesJsResult = new JSONArray ();
    13 
    14                         Hostiles.Instance.Get (enemies);
    15                         for (int i = 0; i < enemies.Count; i++) {
    16                                 EntityEnemy entity = enemies [i];
    17                                 Vector3i position = new Vector3i (entity.GetPosition ());
    18 
    19                                 JSONObject jsonPOS = new JSONObject ();
    20                                 jsonPOS.Add ("x", new JSONNumber (position.x));
    21                                 jsonPOS.Add ("y", new JSONNumber (position.y));
    22                                 jsonPOS.Add ("z", new JSONNumber (position.z));
    23 
    24                                 JSONObject pJson = new JSONObject ();
    25                                 pJson.Add ("id", new JSONNumber (entity.entityId));
    26 
    27                                 if (!string.IsNullOrEmpty (entity.EntityName)) {
    28                                         pJson.Add ("name", new JSONString (entity.EntityName));
    29                                 } else {
    30                                         pJson.Add ("name", new JSONString ("enemy class #" + entity.entityClass));
    31                                 }
    32 
    33                                 pJson.Add ("position", jsonPOS);
    34 
    35                                 hostilesJsResult.Add (pJson);
    36                         }
    37 
    38                         LegacyApiHelper.WriteJSON (_context.Response, hostilesJsResult);
     5        [UsedImplicitly]
     6        internal class GetHostileLocation : GetEntityListAbs<EntityEnemy> {
     7                public GetHostileLocation () : base (Hostiles.Instance.Get) {
    398                }
    409        }
  • binary-improvements/MapRendering/API/GetLandClaims.cs

    r454 r455  
    11using System.Collections.Generic;
    22using System.Net;
    3 using AllocsFixes.JSON;
    43using AllocsFixes.PersistentData;
     4using JetBrains.Annotations;
     5using Utf8Json;
    56using Webserver;
    67using Webserver.Permissions;
     
    89
    910namespace AllocsFixes.WebAPIs {
     11        [UsedImplicitly]
    1012        public class GetLandClaims : AbsWebAPI {
     13                private static readonly byte[] jsonKeyClaimSize = JsonWriter.GetEncodedPropertyNameWithBeginObject ("claimsize");
     14                private static readonly byte[] jsonKeyClaimOwners = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("claimowners");
     15
     16                private static readonly byte[] jsonKeySteamId = JsonWriter.GetEncodedPropertyNameWithBeginObject ("steamid");
     17                private static readonly byte[] jsonKeyCrossPlatformId = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("crossplatformid");
     18                private static readonly byte[] jsonKeyClaimActive = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("claimactive");
     19                private static readonly byte[] jsonKeyPlayerName = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("playername");
     20                private static readonly byte[] jsonKeyClaims = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("claims");
     21
    1122                public override void HandleRequest (RequestContext _context) {
    1223                        PlatformUserIdentifierAbs requestedUserId = null;
     
    2334                        bool bViewAll = PermissionUtils.CanViewAllClaims (_context.PermissionLevel);
    2435
    25                         JSONObject result = new JSONObject ();
    26                         result.Add ("claimsize", new JSONNumber (GamePrefs.GetInt (EnumUtils.Parse<EnumGamePrefs> (nameof(EnumGamePrefs.LandClaimSize)))));
    27 
    28                         JSONArray claimOwners = new JSONArray ();
    29                         result.Add ("claimowners", claimOwners);
    30 
    3136                        LandClaimList.OwnerFilter[] ownerFilters = null;
    3237                        if (requestedUserId != null || !bViewAll) {
     
    3439                                        ownerFilters = new[] {
    3540                                                LandClaimList.UserIdFilter (userId),
    36                                                 LandClaimList.UserIdFilter (requestedUserId)
     41                                                LandClaimList.UserIdFilter (requestedUserId),
    3742                                        };
    3843                                } else if (!bViewAll) {
     
    4752                        Dictionary<Player, List<Vector3i>> claims = LandClaimList.GetLandClaims (ownerFilters, posFilters);
    4853
     54                        JsonWriter writer = new JsonWriter ();
     55                       
     56                        writer.WriteRaw (jsonKeyClaimSize);
     57                        writer.WriteInt32 (GamePrefs.GetInt (EnumUtils.Parse<EnumGamePrefs> (nameof(EnumGamePrefs.LandClaimSize))));
     58                       
     59                        writer.WriteRaw (jsonKeyClaimOwners);
     60                        writer.WriteBeginArray ();
     61                       
     62                        bool first = true;
     63
    4964                        foreach (KeyValuePair<Player, List<Vector3i>> kvp in claims) {
    50                                 JSONObject owner = new JSONObject ();
    51                                 claimOwners.Add (owner);
    52 
    53                                 owner.Add ("steamid", new JSONString (kvp.Key.PlatformId?.CombinedString ?? ""));
    54                                 owner.Add ("crossplatformid", new JSONString (kvp.Key.CrossPlatformId?.CombinedString ?? ""));
    55                                 owner.Add ("claimactive", new JSONBoolean (kvp.Key.LandProtectionActive));
    56 
    57                                 if (kvp.Key.Name.Length > 0) {
    58                                         owner.Add ("playername", new JSONString (kvp.Key.Name));
    59                                 } else {
    60                                         owner.Add ("playername", new JSONNull ());
     65                                if (!first) {
     66                                        writer.WriteValueSeparator ();
    6167                                }
    6268
    63                                 JSONArray claimsJson = new JSONArray ();
    64                                 owner.Add ("claims", claimsJson);
     69                                first = false;
     70                               
     71                                writer.WriteRaw (jsonKeySteamId);
     72                                writer.WriteString (kvp.Key.PlatformId?.CombinedString ?? "");
     73                               
     74                                writer.WriteRaw (jsonKeyCrossPlatformId);
     75                                writer.WriteString (kvp.Key.CrossPlatformId?.CombinedString ?? "");
     76                               
     77                                writer.WriteRaw (jsonKeyClaimActive);
     78                                writer.WriteBoolean (kvp.Key.LandProtectionActive);
     79                               
     80                                writer.WriteRaw (jsonKeyPlayerName);
     81                                if (kvp.Key.Name.Length > 0) {
     82                                        writer.WriteString (kvp.Key.Name);
     83                                } else {
     84                                        writer.WriteNull ();
     85                                }
     86                               
     87                                writer.WriteRaw (jsonKeyClaims);
     88                                writer.WriteBeginArray ();
     89
     90                                bool first2 = true;
    6591
    6692                                foreach (Vector3i v in kvp.Value) {
    67                                         JSONObject claim = new JSONObject ();
    68                                         claim.Add ("x", new JSONNumber (v.x));
    69                                         claim.Add ("y", new JSONNumber (v.y));
    70                                         claim.Add ("z", new JSONNumber (v.z));
     93                                        if (!first2) {
     94                                                writer.WriteValueSeparator ();
     95                                        }
    7196
    72                                         claimsJson.Add (claim);
     97                                        first2 = false;
     98                                       
     99                                        JsonCommons.WriteVector3I (ref writer, v);
    73100                                }
     101                               
     102                                writer.WriteEndArray ();
     103                               
     104                                writer.WriteEndObject ();
    74105                        }
    75106
    76                         LegacyApiHelper.WriteJSON (_context.Response, result);
     107                        writer.WriteEndArray ();
     108                       
     109                        writer.WriteEndObject ();
     110                        WebUtils.WriteJsonData (_context.Response, ref writer);
    77111                }
    78112        }
  • binary-improvements/MapRendering/API/GetLog.cs

    r454 r455  
    11using System.Collections.Generic;
    2 using AllocsFixes.JSON;
     2using JetBrains.Annotations;
     3using Utf8Json;
    34using Webserver;
    45using Webserver.WebAPI;
    56
    67namespace AllocsFixes.WebAPIs {
     8        [UsedImplicitly]
    79        public class GetLog : AbsWebAPI {
    810                private const int MAX_COUNT = 1000;
    911               
     12                private static readonly byte[] jsonKeyFirstLine = JsonWriter.GetEncodedPropertyNameWithBeginObject ("firstLine");
     13                private static readonly byte[] jsonKeyLastLine = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("lastLine");
     14                private static readonly byte[] jsonKeyEntries = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("entries");
     15
     16                private static readonly byte[] jsonKeyEntDate = JsonWriter.GetEncodedPropertyNameWithBeginObject ("date");
     17                private static readonly byte[] jsonKeyEntTime = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("time");
     18                private static readonly byte[] jsonKeyEntUptime = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("uptime");
     19                private static readonly byte[] jsonKeyEntMsg = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("msg");
     20                private static readonly byte[] jsonKeyEntTrace = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("trace");
     21                private static readonly byte[] jsonKeyEntType = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("type");
     22
    1023                public override void HandleRequest (RequestContext _context) {
    1124                        if (_context.Request.QueryString ["count"] == null || !int.TryParse (_context.Request.QueryString ["count"], out var count)) {
     
    2639
    2740                        if (_context.Request.QueryString ["firstLine"] == null || !int.TryParse (_context.Request.QueryString ["firstLine"], out var firstLine)) {
    28                                 if (count > 0) {
    29                                         firstLine = LogBuffer.Instance.OldestLine;
    30                                 } else {
    31                                         firstLine = LogBuffer.Instance.LatestLine;
    32                                 }
     41                                firstLine = count > 0 ? LogBuffer.Instance.OldestLine : LogBuffer.Instance.LatestLine;
    3342                        }
    34 
    35                         JSONObject result = new JSONObject ();
    3643
    3744                        List<LogBuffer.LogEntry> logEntries = LogBuffer.Instance.GetRange (ref firstLine, count, out var lastLine);
    3845
    39                         JSONArray entries = new JSONArray ();
     46                        JsonWriter writer = new JsonWriter ();
     47                       
     48                        writer.WriteRaw (jsonKeyFirstLine);
     49                        writer.WriteInt32 (firstLine);
     50                       
     51                        writer.WriteRaw (jsonKeyLastLine);
     52                        writer.WriteInt32 (lastLine);
     53                       
     54                        writer.WriteRaw (jsonKeyEntries);
     55                        writer.WriteBeginArray ();
     56                       
     57                        bool first = true;
     58
    4059                        foreach (LogBuffer.LogEntry logEntry in logEntries) {
    41                                 JSONObject entry = new JSONObject ();
     60                                if (!first) {
     61                                        writer.WriteValueSeparator ();
     62                                }
     63
     64                                first = false;
     65                               
    4266                                var logEntryTimestamp = logEntry.Timestamp;
    43                                 entry.Add ("date", new JSONString ($"{logEntryTimestamp.Year:0000}-{logEntryTimestamp.Month:00}-{logEntryTimestamp.Day:00}"));
    44                                 entry.Add ("time", new JSONString ($"{logEntryTimestamp.Hour:00}:{logEntryTimestamp.Minute:00}:{logEntryTimestamp.Second:00}"));
    45                                 entry.Add ("uptime", new JSONString (logEntry.Uptime.ToString()));
    46                                 entry.Add ("msg", new JSONString (logEntry.Message));
    47                                 entry.Add ("trace", new JSONString (logEntry.Trace));
    48                                 entry.Add ("type", new JSONString (logEntry.Type.ToStringCached ()));
    49                                 entries.Add (entry);
     67
     68                                writer.WriteRaw (jsonKeyEntDate);
     69                                writer.WriteString ($"{logEntryTimestamp.Year:0000}-{logEntryTimestamp.Month:00}-{logEntryTimestamp.Day:00}");
     70                               
     71                                writer.WriteRaw (jsonKeyEntTime);
     72                                writer.WriteString ($"{logEntryTimestamp.Hour:00}:{logEntryTimestamp.Minute:00}:{logEntryTimestamp.Second:00}");
     73                               
     74                                writer.WriteRaw (jsonKeyEntUptime);
     75                                writer.WriteString (logEntry.Uptime.ToString());
     76                               
     77                                writer.WriteRaw (jsonKeyEntMsg);
     78                                writer.WriteString (logEntry.Message);
     79                               
     80                                writer.WriteRaw (jsonKeyEntTrace);
     81                                writer.WriteString (logEntry.Trace);
     82                               
     83                                writer.WriteRaw (jsonKeyEntType);
     84                                writer.WriteString (logEntry.Type.ToStringCached ());
     85
     86                                writer.WriteEndObject ();
    5087                        }
    5188
    52                         result.Add ("firstLine", new JSONNumber (firstLine));
    53                         result.Add ("lastLine", new JSONNumber (lastLine));
    54                         result.Add ("entries", entries);
    55 
    56                         LegacyApiHelper.WriteJSON (_context.Response, result);
     89                        writer.WriteEndArray ();
     90                       
     91                        writer.WriteEndObject ();
     92                        WebUtils.WriteJsonData (_context.Response, ref writer);
    5793                }
    5894        }
  • binary-improvements/MapRendering/API/GetPlayerInventories.cs

    r454 r455  
    11using System.Collections.Generic;
    2 using AllocsFixes.JSON;
    32using AllocsFixes.PersistentData;
     3using JetBrains.Annotations;
     4using Utf8Json;
    45using Webserver;
    56using Webserver.WebAPI;
    67
    78namespace AllocsFixes.WebAPIs {
     9        [UsedImplicitly]
    810        public class GetPlayerInventories : AbsWebAPI {
    911                public override void HandleRequest (RequestContext _context) {
    1012                        GetPlayerInventory.GetInventoryArguments (_context, out bool showIconColor, out bool showIconName);
    1113
    12                         JSONArray AllInventoriesResult = new JSONArray ();
     14                        JsonWriter writer = new JsonWriter ();
     15                       
     16                        writer.WriteBeginArray ();
     17                       
     18                        bool first = true;
    1319
    1420                        foreach (KeyValuePair<PlatformUserIdentifierAbs, Player> kvp in PersistentContainer.Instance.Players.Dict) {
     
    2026
    2127                                if (p.IsOnline) {
    22                                         AllInventoriesResult.Add (GetPlayerInventory.DoPlayer (p, showIconColor, showIconName));
     28                                        if (!first) {
     29                                                writer.WriteValueSeparator ();
     30                                        }
     31
     32                                        first = false;
     33                               
     34                                        GetPlayerInventory.DoPlayer (ref writer, p, showIconColor, showIconName);
    2335                                }
    2436                        }
    25 
    26                         LegacyApiHelper.WriteJSON (_context.Response, AllInventoriesResult);
     37                       
     38                        writer.WriteEndArray ();
     39                       
     40                        WebUtils.WriteJsonData (_context.Response, ref writer);
    2741                }
    2842        }
  • binary-improvements/MapRendering/API/GetPlayerInventory.cs

    r454 r455  
    11using System.Collections.Generic;
    22using System.Net;
    3 using AllocsFixes.JSON;
    43using AllocsFixes.PersistentData;
     4using JetBrains.Annotations;
     5using Utf8Json;
    56using Webserver;
    67using Webserver.WebAPI;
    78
    89namespace AllocsFixes.WebAPIs {
     10        [UsedImplicitly]
    911        public class GetPlayerInventory : AbsWebAPI {
    1012                public override void HandleRequest (RequestContext _context) {
     
    2830                        GetInventoryArguments (_context, out bool showIconColor, out bool showIconName);
    2931
    30                         JSONObject result = DoPlayer (p, showIconColor, showIconName);
    31 
    32                         LegacyApiHelper.WriteJSON (_context.Response, result);
     32                        JsonWriter writer = new JsonWriter ();
     33                        DoPlayer (ref writer, p, showIconColor, showIconName);
     34                        WebUtils.WriteJsonData (_context.Response, ref writer);
    3335                }
    3436
     
    4345                }
    4446
    45                 internal static JSONObject DoPlayer (Player _player, bool _showIconColor, bool _showIconName) {
     47                private static readonly byte[] jsonKeyUserId = JsonWriter.GetEncodedPropertyNameWithBeginObject ("userid");
     48                private static readonly byte[] jsonKeyCrossPlatformId = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("crossplatformid");
     49                private static readonly byte[] jsonKeyEntityId = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("entityid");
     50                private static readonly byte[] jsonKeyPlayerName = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("playername");
     51                private static readonly byte[] jsonKeyBag = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("bag");
     52                private static readonly byte[] jsonKeyBelt = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("belt");
     53                private static readonly byte[] jsonKeyEquipment = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("equipment");
     54
     55                internal static void DoPlayer (ref JsonWriter _writer, Player _player, bool _showIconColor, bool _showIconName) {
    4656                        PersistentData.Inventory inv = _player.Inventory;
    47 
    48                         JSONObject result = new JSONObject ();
    49 
    50                         JSONArray bag = new JSONArray ();
    51                         JSONArray belt = new JSONArray ();
    52                         JSONObject equipment = new JSONObject ();
    53                         result.Add ("userid", new JSONString (_player.PlatformId.CombinedString));
    54                         result.Add ("crossplatformid", new JSONString (_player.CrossPlatformId?.CombinedString ?? ""));
    55                         result.Add ("entityid", new JSONNumber (_player.EntityID));
    56                         result.Add ("playername", new JSONString (_player.Name));
    57                         result.Add ("bag", bag);
    58                         result.Add ("belt", belt);
    59                         result.Add ("equipment", equipment);
    60 
    61                         DoInventory (belt, inv.belt, _showIconColor, _showIconName);
    62                         DoInventory (bag, inv.bag, _showIconColor, _showIconName);
    63 
    64                         AddEquipment (equipment, "head", inv.equipment, EquipmentSlots.Headgear, _showIconColor, _showIconName);
    65                         AddEquipment (equipment, "eyes", inv.equipment, EquipmentSlots.Eyewear, _showIconColor, _showIconName);
    66                         AddEquipment (equipment, "face", inv.equipment, EquipmentSlots.Face, _showIconColor, _showIconName);
    67 
    68                         AddEquipment (equipment, "armor", inv.equipment, EquipmentSlots.ChestArmor, _showIconColor, _showIconName);
    69                         AddEquipment (equipment, "jacket", inv.equipment, EquipmentSlots.Jacket, _showIconColor, _showIconName);
    70                         AddEquipment (equipment, "shirt", inv.equipment, EquipmentSlots.Shirt, _showIconColor, _showIconName);
    71 
    72                         AddEquipment (equipment, "legarmor", inv.equipment, EquipmentSlots.LegArmor, _showIconColor, _showIconName);
    73                         AddEquipment (equipment, "pants", inv.equipment, EquipmentSlots.Legs, _showIconColor, _showIconName);
    74                         AddEquipment (equipment, "boots", inv.equipment, EquipmentSlots.Feet, _showIconColor, _showIconName);
    75 
    76                         AddEquipment (equipment, "gloves", inv.equipment, EquipmentSlots.Hands, _showIconColor, _showIconName);
    77 
    78                         return result;
     57                       
     58                        _writer.WriteRaw (jsonKeyUserId);
     59                        _writer.WriteString (_player.PlatformId.CombinedString);
     60                       
     61                        _writer.WriteRaw (jsonKeyCrossPlatformId);
     62                        _writer.WriteString (_player.CrossPlatformId?.CombinedString ?? "");
     63                       
     64                        _writer.WriteRaw (jsonKeyEntityId);
     65                        _writer.WriteInt32 (_player.EntityID);
     66                       
     67                        _writer.WriteRaw (jsonKeyPlayerName);
     68                        _writer.WriteString (_player.Name);
     69                       
     70                        _writer.WriteRaw (jsonKeyBag);
     71                        DoInventory (ref _writer, inv.bag, _showIconColor, _showIconName);
     72                       
     73                        _writer.WriteRaw (jsonKeyBelt);
     74                        DoInventory (ref _writer, inv.belt, _showIconColor, _showIconName);
     75                       
     76                        _writer.WriteRaw (jsonKeyEquipment);
     77                        DoEquipment (ref _writer, inv.equipment, _showIconColor, _showIconName);
     78                       
     79                        _writer.WriteEndObject ();
    7980                }
    8081
    81                 private static void DoInventory (JSONArray _jsonRes, List<InvItem> _inv, bool _showIconColor, bool _showIconName) {
     82                private static void DoInventory (ref JsonWriter _writer, IReadOnlyList<InvItem> _inv, bool _showIconColor, bool _showIconName) {
     83                        _writer.WriteBeginArray ();
    8284                        for (int i = 0; i < _inv.Count; i++) {
    83                                 _jsonRes.Add (GetJsonForItem (_inv [i], _showIconColor, _showIconName));
     85                                if (i > 0) {
     86                                        _writer.WriteValueSeparator ();
     87                                }
     88                                GetJsonForItem (ref _writer, _inv [i], _showIconColor, _showIconName);
    8489                        }
     90                        _writer.WriteEndArray ();
    8591                }
    8692
    87                 private static void AddEquipment (JSONObject _eq, string _slotname, InvItem[] _items, EquipmentSlots _slot, bool _showIconColor, bool _showIconName) {
     93                private static void DoEquipment (ref JsonWriter _writer, IReadOnlyList<InvItem> _equ, bool _showIconColor, bool _showIconName) {
     94                        _writer.WriteBeginObject ();
     95                       
     96                        AddEquipment (ref _writer, "head", _equ, EquipmentSlots.Headgear, _showIconColor, _showIconName);
     97                        _writer.WriteValueSeparator ();
     98                        AddEquipment (ref _writer, "eyes", _equ, EquipmentSlots.Eyewear, _showIconColor, _showIconName);
     99                        _writer.WriteValueSeparator ();
     100                        AddEquipment (ref _writer, "face", _equ, EquipmentSlots.Face, _showIconColor, _showIconName);
     101                        _writer.WriteValueSeparator ();
     102
     103                        AddEquipment (ref _writer, "armor", _equ, EquipmentSlots.ChestArmor, _showIconColor, _showIconName);
     104                        _writer.WriteValueSeparator ();
     105                        AddEquipment (ref _writer, "jacket", _equ, EquipmentSlots.Jacket, _showIconColor, _showIconName);
     106                        _writer.WriteValueSeparator ();
     107                        AddEquipment (ref _writer, "shirt", _equ, EquipmentSlots.Shirt, _showIconColor, _showIconName);
     108                        _writer.WriteValueSeparator ();
     109
     110                        AddEquipment (ref _writer, "legarmor", _equ, EquipmentSlots.LegArmor, _showIconColor, _showIconName);
     111                        _writer.WriteValueSeparator ();
     112                        AddEquipment (ref _writer, "pants", _equ, EquipmentSlots.Legs, _showIconColor, _showIconName);
     113                        _writer.WriteValueSeparator ();
     114                        AddEquipment (ref _writer, "boots", _equ, EquipmentSlots.Feet, _showIconColor, _showIconName);
     115                        _writer.WriteValueSeparator ();
     116
     117                        AddEquipment (ref _writer, "gloves", _equ, EquipmentSlots.Hands, _showIconColor, _showIconName);
     118                       
     119                        _writer.WriteEndObject ();
     120                }
     121
     122                private static void AddEquipment (ref JsonWriter _writer, string _slotname, IReadOnlyList<InvItem> _items, EquipmentSlots _slot, bool _showIconColor, bool _showIconName) {
     123                        _writer.WritePropertyName (_slotname);
     124
    88125                        int[] slotindices = XUiM_PlayerEquipment.GetSlotIndicesByEquipmentSlot (_slot);
    89126
     
    91128                                if (_items? [slotindices [i]] != null) {
    92129                                        InvItem item = _items [slotindices [i]];
    93                                         _eq.Add (_slotname, GetJsonForItem (item, _showIconColor, _showIconName));
     130                                       
     131                                        GetJsonForItem (ref _writer, item, _showIconColor, _showIconName);
    94132                                        return;
    95133                                }
    96134                        }
    97135
    98                         _eq.Add (_slotname, new JSONNull ());
     136                        // Slot not found / empty
     137                        _writer.WriteNull ();
    99138                }
    100139
    101                 private static JSONNode GetJsonForItem (InvItem _item, bool _showIconColor, bool _showIconName) {
     140                private static readonly byte[] jsonKeyCount = JsonWriter.GetEncodedPropertyNameWithBeginObject ("count");
     141                private static readonly byte[] jsonKeyName = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("name");
     142                private static readonly byte[] jsonKeyIcon = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("icon");
     143                private static readonly byte[] jsonKeyIconColor = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("iconcolor");
     144                private static readonly byte[] jsonKeyQuality = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("quality");
     145                private static readonly byte[] jsonKeyQualityColor = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("qualitycolor");
     146
     147                private static void GetJsonForItem (ref JsonWriter _writer, InvItem _item, bool _showIconColor, bool _showIconName) {
    102148                        if (_item == null) {
    103                                 return new JSONNull ();
     149                                _writer.WriteNull ();
     150                                return;
    104151                        }
    105 
    106                         JSONObject jsonItem = new JSONObject ();
    107                         jsonItem.Add ("count", new JSONNumber (_item.count));
    108                         jsonItem.Add ("name", new JSONString (_item.itemName));
     152                       
     153                        _writer.WriteRaw (jsonKeyCount);
     154                        _writer.WriteInt32 (_item.count);
     155                       
     156                        _writer.WriteRaw (jsonKeyName);
     157                        _writer.WriteString (_item.itemName);
    109158                       
    110159                        if (_showIconName) {
    111                                 jsonItem.Add ("icon", new JSONString (_item.icon));
     160                                _writer.WriteRaw (jsonKeyIcon);
     161                                _writer.WriteString (_item.icon);
    112162                        }
    113163
    114164                        if (_showIconColor) {
    115                                 jsonItem.Add ("iconcolor", new JSONString (_item.iconcolor));
     165                                _writer.WriteRaw (jsonKeyIconColor);
     166                                _writer.WriteString (_item.iconcolor);
    116167                        }
    117168
    118                         jsonItem.Add ("quality", new JSONNumber (_item.quality));
     169                        _writer.WriteRaw (jsonKeyQuality);
     170                        _writer.WriteInt32 (_item.quality);
     171
    119172                        if (_item.quality >= 0) {
    120                                 jsonItem.Add ("qualitycolor", new JSONString (QualityInfo.GetQualityColorHex (_item.quality)));
     173                                _writer.WriteRaw (jsonKeyQualityColor);
     174                                _writer.WriteString (QualityInfo.GetQualityColorHex (_item.quality));
    121175                        }
    122 
    123                         return jsonItem;
    124 
     176                       
     177                        _writer.WriteEndObject ();
    125178                }
    126179        }
  • binary-improvements/MapRendering/API/GetPlayerList.cs

    r454 r455  
    22using System.Collections.Generic;
    33using System.Linq;
     4using System.Text;
    45using System.Text.RegularExpressions;
    5 using AllocsFixes.JSON;
    66using AllocsFixes.PersistentData;
     7using JetBrains.Annotations;
    78using Webserver;
    89using Webserver.Permissions;
     
    1011
    1112namespace AllocsFixes.WebAPIs {
     13        [UsedImplicitly]
    1214        public class GetPlayerList : AbsWebAPI {
    1315                private static readonly Regex numberFilterMatcher =
     
    121123                        result.Add ("players", playersJsResult);
    122124
    123                         LegacyApiHelper.WriteJSON (_context.Response, result);
    124                 }
    125 
    126                 private IEnumerable<JSONObject> ExecuteFilter (IEnumerable<JSONObject> _list, string _filterCol,
     125                        StringBuilder sb = new StringBuilder ();
     126                        result.ToString (sb);
     127                        WebUtils.WriteText (_context.Response, sb.ToString(), _mimeType: WebUtils.MimeJson);
     128                }
     129
     130                private static IEnumerable<JSONObject> ExecuteFilter (IEnumerable<JSONObject> _list, string _filterCol,
    127131                        string _filterVal) {
    128132                        if (!_list.Any()) {
     
    144148                                        // regex-match whole ^string$, replace * by .*, ? by .?, + by .+
    145149                                        _filterVal = _filterVal.Replace ("*", ".*").Replace ("?", ".?").Replace ("+", ".+");
    146                                         _filterVal = "^" + _filterVal + "$";
     150                                        _filterVal = $"^{_filterVal}$";
    147151
    148152                                        //Log.Out ("GetPlayerList: Filter on String with Regex '" + _filterVal + "'");
     
    156160
    157161
    158                 private IEnumerable<JSONObject> ExecuteNumberFilter (IEnumerable<JSONObject> _list, string _filterCol,
     162                private static IEnumerable<JSONObject> ExecuteNumberFilter (IEnumerable<JSONObject> _list, string _filterCol,
    159163                        string _filterVal) {
    160164                        // allow value (exact match), =, ==, >=, >, <=, <
     
    207211                        }
    208212
    209                         Log.Out ("GetPlayerList: ignoring invalid filter for number-column '{0}': '{1}'", _filterCol, _filterVal);
     213                        Log.Out ($"GetPlayerList: ignoring invalid filter for number-column '{_filterCol}': '{_filterVal}'");
    210214                        return _list;
    211215                }
    212216
    213217
    214                 private IEnumerable<JSONObject> ExecuteSort (IEnumerable<JSONObject> _list, string _sortCol, bool _ascending) {
     218                private static IEnumerable<JSONObject> ExecuteSort (IEnumerable<JSONObject> _list, string _sortCol, bool _ascending) {
    215219                        if (_list.Count () == 0) {
    216220                                return _list;
     
    246250
    247251
    248                 private bool NearlyEqual (double _a, double _b, double _epsilon) {
     252                private static bool NearlyEqual (double _a, double _b, double _epsilon) {
    249253                        double absA = Math.Abs (_a);
    250254                        double absB = Math.Abs (_b);
     
    267271                        GreaterEqual,
    268272                        Lesser,
    269                         LesserEqual
    270                 }
     273                        LesserEqual,
     274                }
     275
     276
     277#region JSON encoder
     278
     279                private abstract class JSONNode {
     280                        public abstract void ToString (StringBuilder _stringBuilder, bool _prettyPrint = false, int _currentLevel = 0);
     281
     282                        public override string ToString () {
     283                                StringBuilder sb = new StringBuilder ();
     284                                ToString (sb);
     285                                return sb.ToString ();
     286                        }
     287                }
     288
     289                private abstract class JSONValue : JSONNode {
     290                }
     291
     292                private class JSONNull : JSONValue {
     293                        public override void ToString (StringBuilder _stringBuilder, bool _prettyPrint = false, int _currentLevel = 0) {
     294                                _stringBuilder.Append ("null");
     295                        }
     296                }
     297
     298                private class JSONBoolean : JSONValue {
     299                        private readonly bool value;
     300
     301                        public JSONBoolean (bool _value) {
     302                                value = _value;
     303                        }
     304
     305                        public bool GetBool () {
     306                                return value;
     307                        }
     308
     309                        public override void ToString (StringBuilder _stringBuilder, bool _prettyPrint = false, int _currentLevel = 0) {
     310                                _stringBuilder.Append (value ? "true" : "false");
     311                        }
     312                }
     313
     314                private class JSONNumber : JSONValue {
     315                        private readonly double value;
     316
     317                        public JSONNumber (double _value) {
     318                                value = _value;
     319                        }
     320
     321                        public double GetDouble () {
     322                                return value;
     323                        }
     324
     325                        public override void ToString (StringBuilder _stringBuilder, bool _prettyPrint = false, int _currentLevel = 0) {
     326                                _stringBuilder.Append (value.ToCultureInvariantString ());
     327                        }
     328                }
     329
     330                private class JSONString : JSONValue {
     331                        private readonly string value;
     332
     333                        public JSONString (string _value) {
     334                                value = _value;
     335                        }
     336
     337                        public string GetString () {
     338                                return value;
     339                        }
     340
     341                        public override void ToString (StringBuilder _stringBuilder, bool _prettyPrint = false, int _currentLevel = 0) {
     342                                if (string.IsNullOrEmpty (value)) {
     343                                        _stringBuilder.Append ("\"\"");
     344                                        return;
     345                                }
     346
     347                                int len = value.Length;
     348
     349                                _stringBuilder.EnsureCapacity (_stringBuilder.Length + 2 * len);
     350
     351                                _stringBuilder.Append ('"');
     352
     353                                foreach (char c in value) {
     354                                        switch (c) {
     355                                                case '\\':
     356                                                case '"':
     357
     358//                                      case '/':
     359                                                        _stringBuilder.Append ('\\');
     360                                                        _stringBuilder.Append (c);
     361                                                        break;
     362                                                case '\b':
     363                                                        _stringBuilder.Append ("\\b");
     364                                                        break;
     365                                                case '\t':
     366                                                        _stringBuilder.Append ("\\t");
     367                                                        break;
     368                                                case '\n':
     369                                                        _stringBuilder.Append ("\\n");
     370                                                        break;
     371                                                case '\f':
     372                                                        _stringBuilder.Append ("\\f");
     373                                                        break;
     374                                                case '\r':
     375                                                        _stringBuilder.Append ("\\r");
     376                                                        break;
     377                                                default:
     378                                                        if (c < ' ') {
     379                                                                _stringBuilder.Append ("\\u");
     380                                                                _stringBuilder.Append (((int) c).ToString ("X4"));
     381                                                        } else {
     382                                                                _stringBuilder.Append (c);
     383                                                        }
     384
     385                                                        break;
     386                                        }
     387                                }
     388
     389                                _stringBuilder.Append ('"');
     390                        }
     391
     392                }
     393
     394                private class JSONArray : JSONNode {
     395                        private readonly List<JSONNode> nodes = new List<JSONNode> ();
     396
     397                        public void Add (JSONNode _node) {
     398                                nodes.Add (_node);
     399                        }
     400
     401                        public override void ToString (StringBuilder _stringBuilder, bool _prettyPrint = false, int _currentLevel = 0) {
     402                                _stringBuilder.Append ("[");
     403                                if (_prettyPrint) {
     404                                        _stringBuilder.Append ('\n');
     405                                }
     406
     407                                foreach (JSONNode n in nodes) {
     408                                        if (_prettyPrint) {
     409                                                _stringBuilder.Append (new string ('\t', _currentLevel + 1));
     410                                        }
     411
     412                                        n.ToString (_stringBuilder, _prettyPrint, _currentLevel + 1);
     413                                        _stringBuilder.Append (",");
     414                                        if (_prettyPrint) {
     415                                                _stringBuilder.Append ('\n');
     416                                        }
     417                                }
     418
     419                                if (nodes.Count > 0) {
     420                                        _stringBuilder.Remove (_stringBuilder.Length - (_prettyPrint ? 2 : 1), 1);
     421                                }
     422
     423                                if (_prettyPrint) {
     424                                        _stringBuilder.Append (new string ('\t', _currentLevel));
     425                                }
     426
     427                                _stringBuilder.Append ("]");
     428                        }
     429
     430                }
     431
     432                private class JSONObject : JSONNode {
     433                        private readonly Dictionary<string, JSONNode> nodes = new Dictionary<string, JSONNode> ();
     434
     435                        public JSONNode this [string _name] => nodes [_name];
     436
     437                        public bool ContainsKey (string _name) {
     438                                return nodes.ContainsKey (_name);
     439                        }
     440
     441                        public void Add (string _name, JSONNode _node) {
     442                                nodes.Add (_name, _node);
     443                        }
     444
     445                        public override void ToString (StringBuilder _stringBuilder, bool _prettyPrint = false, int _currentLevel = 0) {
     446                                _stringBuilder.Append ("{");
     447                                if (_prettyPrint) {
     448                                        _stringBuilder.Append ('\n');
     449                                }
     450
     451                                foreach (KeyValuePair<string, JSONNode> kvp in nodes) {
     452                                        if (_prettyPrint) {
     453                                                _stringBuilder.Append (new string ('\t', _currentLevel + 1));
     454                                        }
     455
     456                                        _stringBuilder.Append ($"\"{kvp.Key}\":");
     457                                        if (_prettyPrint) {
     458                                                _stringBuilder.Append (" ");
     459                                        }
     460
     461                                        kvp.Value.ToString (_stringBuilder, _prettyPrint, _currentLevel + 1);
     462                                        _stringBuilder.Append (",");
     463                                        if (_prettyPrint) {
     464                                                _stringBuilder.Append ('\n');
     465                                        }
     466                                }
     467
     468                                if (nodes.Count > 0) {
     469                                        _stringBuilder.Remove (_stringBuilder.Length - (_prettyPrint ? 2 : 1), 1);
     470                                }
     471
     472                                if (_prettyPrint) {
     473                                        _stringBuilder.Append (new string ('\t', _currentLevel));
     474                                }
     475
     476                                _stringBuilder.Append ("}");
     477                        }
     478
     479                }
     480               
     481#endregion
     482
    271483        }
    272484}
  • binary-improvements/MapRendering/API/GetPlayersLocation.cs

    r454 r455  
    11using System.Collections.Generic;
    2 using AllocsFixes.JSON;
    32using AllocsFixes.PersistentData;
     3using JetBrains.Annotations;
     4using Utf8Json;
    45using Webserver;
    56using Webserver.Permissions;
     
    78
    89namespace AllocsFixes.WebAPIs {
     10        [UsedImplicitly]
    911        public class GetPlayersLocation : AbsWebAPI {
     12                private static readonly byte[] jsonKeySteamId = JsonWriter.GetEncodedPropertyNameWithBeginObject ("steamid");
     13                private static readonly byte[] jsonKeyCrossPlatformId = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("crossplatformid");
     14                private static readonly byte[] jsonKeyName = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("name");
     15                private static readonly byte[] jsonKeyOnline = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("online");
     16                private static readonly byte[] jsonKeyPosition = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("position");
     17
    1018                public override void HandleRequest (RequestContext _context) {
    1119                        AdminTools admTools = GameManager.Instance.adminTools;
     
    1927                        bool bViewAll = PermissionUtils.CanViewAllPlayers (_context.PermissionLevel);
    2028
    21                         JSONArray playersJsResult = new JSONArray ();
     29                        JsonWriter writer = new JsonWriter ();
     30                       
     31                        writer.WriteBeginArray ();
     32                       
     33                        bool first = true;
    2234
    2335                        Players playersList = PersistentContainer.Instance.Players;
     
    3446                                if (listOffline || p.IsOnline) {
    3547                                        if (bViewAll || p.InternalId.Equals (userId)) {
    36                                                 JSONObject pos = new JSONObject ();
    37                                                 pos.Add ("x", new JSONNumber (p.LastPosition.x));
    38                                                 pos.Add ("y", new JSONNumber (p.LastPosition.y));
    39                                                 pos.Add ("z", new JSONNumber (p.LastPosition.z));
    4048
    41                                                 JSONObject pJson = new JSONObject ();
    42                                                 pJson.Add ("steamid", new JSONString (kvp.Value.PlatformId.CombinedString));
    43                                                 pJson.Add ("crossplatformid", new JSONString (kvp.Value.CrossPlatformId?.CombinedString ?? ""));
     49                                                if (!first) {
     50                                                        writer.WriteValueSeparator ();
     51                                                }
    4452
    45                                                 //                                      pJson.Add("entityid", new JSONNumber (p.EntityID));
    46                                                 //                    pJson.Add("ip", new JSONString (p.IP));
    47                                                 pJson.Add ("name", new JSONString (p.Name));
    48                                                 pJson.Add ("online", new JSONBoolean (p.IsOnline));
    49                                                 pJson.Add ("position", pos);
    50 
    51                                                 //                                      pJson.Add ("totalplaytime", new JSONNumber (p.TotalPlayTime));
    52                                                 //                                      pJson.Add ("lastonline", new JSONString (p.LastOnline.ToString ("s")));
    53                                                 //                                      pJson.Add ("ping", new JSONNumber (p.IsOnline ? p.ClientInfo.ping : -1));
    54 
    55                                                 playersJsResult.Add (pJson);
     53                                                first = false;
     54                               
     55                                                writer.WriteRaw (jsonKeySteamId);
     56                                                writer.WriteString (kvp.Value.PlatformId.CombinedString);
     57                               
     58                                                writer.WriteRaw (jsonKeyCrossPlatformId);
     59                                                writer.WriteString (kvp.Value.CrossPlatformId?.CombinedString ?? "");
     60                               
     61                                                writer.WriteRaw (jsonKeyName);
     62                                                writer.WriteString (p.Name);
     63                               
     64                                                writer.WriteRaw (jsonKeyOnline);
     65                                                writer.WriteBoolean (p.IsOnline);
     66                               
     67                                                writer.WriteRaw (jsonKeyPosition);
     68                                                JsonCommons.WriteVector3I (ref writer, p.LastPosition);
     69                               
     70                                                writer.WriteEndObject ();
    5671                                        }
    5772                                }
    5873                        }
    59 
    60                         LegacyApiHelper.WriteJSON (_context.Response, playersJsResult);
     74                       
     75                        writer.WriteEndArray ();
     76                       
     77                        WebUtils.WriteJsonData (_context.Response, ref writer);
    6178                }
    6279        }
  • binary-improvements/MapRendering/API/GetPlayersOnline.cs

    r454 r455  
    11using System.Collections.Generic;
    2 using AllocsFixes.JSON;
    32using AllocsFixes.PersistentData;
     3using JetBrains.Annotations;
     4using Utf8Json;
    45using Webserver;
    56using Webserver.WebAPI;
    67
    78namespace AllocsFixes.WebAPIs {
     9        [UsedImplicitly]
    810        public class GetPlayersOnline : AbsWebAPI {
     11                private static readonly byte[] jsonKeySteamId = JsonWriter.GetEncodedPropertyNameWithBeginObject ("steamid");
     12                private static readonly byte[] jsonKeyCrossPlatformId = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("crossplatformid");
     13                private static readonly byte[] jsonKeyEntityId = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("entityid");
     14                private static readonly byte[] jsonKeyIp = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("ip");
     15                private static readonly byte[] jsonKeyName = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("name");
     16                private static readonly byte[] jsonKeyOnline = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("online");
     17                private static readonly byte[] jsonKeyPosition = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("position");
     18
     19                private static readonly byte[] jsonKeyLevel = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("level");
     20                private static readonly byte[] jsonKeyHealth = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("health");
     21                private static readonly byte[] jsonKeyStamina = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("stamina");
     22                private static readonly byte[] jsonKeyZombieKills = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("zombiekills");
     23                private static readonly byte[] jsonKeyPlayerKills = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("playerkills");
     24                private static readonly byte[] jsonKeyPlayerDeaths = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("playerdeaths");
     25                private static readonly byte[] jsonKeyScore = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("score");
     26
     27                private static readonly byte[] jsonKeyTotalPlaytime = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("totalplaytime");
     28                private static readonly byte[] jsonKeyLastOnline = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("lastonline");
     29                private static readonly byte[] jsonKeyPing = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("ping");
     30
    931                public override void HandleRequest (RequestContext _context) {
    10                         JSONArray players = new JSONArray ();
     32                        JsonWriter writer = new JsonWriter ();
     33                       
     34                        writer.WriteBeginArray ();
     35                       
     36                        bool first = true;
    1137
    1238                        World w = GameManager.Instance.World;
     
    1541                                Player player = PersistentContainer.Instance.Players.GetByInternalId (ci.InternalId);
    1642
    17                                 JSONObject pos = new JSONObject ();
    18                                 pos.Add ("x", new JSONNumber ((int) current.Value.GetPosition ().x));
    19                                 pos.Add ("y", new JSONNumber ((int) current.Value.GetPosition ().y));
    20                                 pos.Add ("z", new JSONNumber ((int) current.Value.GetPosition ().z));
     43                                if (!first) {
     44                                        writer.WriteValueSeparator ();
     45                                }
    2146
    22                                 JSONObject p = new JSONObject ();
    23                                 p.Add ("steamid", new JSONString (ci.PlatformId.CombinedString));
    24                                 p.Add ("crossplatformid", new JSONString (ci.CrossplatformId?.CombinedString ?? ""));
    25                                 p.Add ("entityid", new JSONNumber (ci.entityId));
    26                                 p.Add ("ip", new JSONString (ci.ip));
    27                                 p.Add ("name", new JSONString (current.Value.EntityName));
    28                                 p.Add ("online", new JSONBoolean (true));
    29                                 p.Add ("position", pos);
     47                                first = false;
     48                               
     49                                writer.WriteRaw (jsonKeySteamId);
     50                                writer.WriteString (ci.PlatformId.CombinedString);
     51                               
     52                                writer.WriteRaw (jsonKeyCrossPlatformId);
     53                                writer.WriteString (ci.CrossplatformId?.CombinedString ?? "");
     54                               
     55                                writer.WriteRaw (jsonKeyEntityId);
     56                                writer.WriteInt32 (ci.entityId);
     57                               
     58                                writer.WriteRaw (jsonKeyIp);
     59                                writer.WriteString (ci.ip);
     60                               
     61                                writer.WriteRaw (jsonKeyName);
     62                                writer.WriteString (current.Value.EntityName);
     63                               
     64                                writer.WriteRaw (jsonKeyOnline);
     65                                writer.WriteBoolean (true);
     66                               
     67                                writer.WriteRaw (jsonKeyPosition);
     68                                JsonCommons.WriteVector3I (ref writer, new Vector3i (current.Value.GetPosition ()));
     69                               
     70                                writer.WriteRaw (jsonKeyLevel);
     71                                writer.WriteSingle (player?.Level ?? -1);
     72                               
     73                                writer.WriteRaw (jsonKeyHealth);
     74                                writer.WriteInt32 (current.Value.Health);
     75                               
     76                                writer.WriteRaw (jsonKeyStamina);
     77                                writer.WriteSingle (current.Value.Stamina);
     78                               
     79                                writer.WriteRaw (jsonKeyZombieKills);
     80                                writer.WriteInt32 (current.Value.KilledZombies);
     81                               
     82                                writer.WriteRaw (jsonKeyPlayerKills);
     83                                writer.WriteInt32 (current.Value.KilledPlayers);
     84                               
     85                                writer.WriteRaw (jsonKeyPlayerDeaths);
     86                                writer.WriteInt32 (current.Value.Died);
     87                               
     88                                writer.WriteRaw (jsonKeyScore);
     89                                writer.WriteInt32 (current.Value.Score);
    3090
    31                                 p.Add ("level", new JSONNumber (player?.Level ?? -1));
    32                                 p.Add ("health", new JSONNumber (current.Value.Health));
    33                                 p.Add ("stamina", new JSONNumber (current.Value.Stamina));
    34                                 p.Add ("zombiekills", new JSONNumber (current.Value.KilledZombies));
    35                                 p.Add ("playerkills", new JSONNumber (current.Value.KilledPlayers));
    36                                 p.Add ("playerdeaths", new JSONNumber (current.Value.Died));
    37                                 p.Add ("score", new JSONNumber (current.Value.Score));
     91                                writer.WriteRaw (jsonKeyTotalPlaytime);
     92                                writer.WriteInt64 (player?.TotalPlayTime ?? -1);
     93                               
     94                                writer.WriteRaw (jsonKeyLastOnline);
     95                                writer.WriteString (player != null ? player.LastOnline.ToString ("s") : string.Empty);
    3896
    39                                 p.Add ("totalplaytime", new JSONNumber (player?.TotalPlayTime ?? -1));
    40                                 p.Add ("lastonline", new JSONString (player != null ? player.LastOnline.ToString ("s") : string.Empty));
    41                                 p.Add ("ping", new JSONNumber (ci.ping));
    42 
    43                                 players.Add (p);
     97                                writer.WriteRaw (jsonKeyPing);
     98                                writer.WriteInt32 (ci.ping);
     99                               
     100                                writer.WriteEndObject ();
    44101                        }
    45 
    46                         LegacyApiHelper.WriteJSON (_context.Response, players);
     102                       
     103                        writer.WriteEndArray ();
     104                       
     105                        WebUtils.WriteJsonData (_context.Response, ref writer);
    47106                }
    48107        }
  • binary-improvements/MapRendering/API/GetServerInfo.cs

    r454 r455  
    11using System;
    2 using AllocsFixes.JSON;
     2using JetBrains.Annotations;
     3using Utf8Json;
    34using Webserver;
    45using Webserver.WebAPI;
    56
    67namespace AllocsFixes.WebAPIs {
     8        [UsedImplicitly]
    79        public class GetServerInfo : AbsWebAPI {
     10                private static readonly byte[] jsonKeyType = JsonWriter.GetEncodedPropertyNameWithBeginObject ("type");
     11                private static readonly byte[] jsonKeyValue = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("value");
     12
    813                public override void HandleRequest (RequestContext _context) {
    9                         JSONObject serverInfo = new JSONObject ();
     14                        GameServerInfo gsi = ConnectionManager.Instance.LocalServerInfo;
    1015
    11                         GameServerInfo gsi = ConnectionManager.Instance.LocalServerInfo;
     16                        JsonWriter writer = new JsonWriter ();
     17                        writer.WriteBeginObject ();
     18
     19                        bool first = true;
    1220
    1321                        foreach (string stringGamePref in Enum.GetNames (typeof (GameInfoString))) {
    1422                                string value = gsi.GetValue ((GameInfoString) Enum.Parse (typeof (GameInfoString), stringGamePref));
     23                               
     24                                if (!first) {
     25                                        writer.WriteValueSeparator ();
     26                                }
    1527
    16                                 JSONObject singleStat = new JSONObject ();
    17                                 singleStat.Add ("type", new JSONString ("string"));
    18                                 singleStat.Add ("value", new JSONString (value));
     28                                first = false;
    1929
    20                                 serverInfo.Add (stringGamePref, singleStat);
     30                                writer.WritePropertyName (stringGamePref);
     31                                writer.WriteRaw (jsonKeyType);
     32                                writer.WriteString ("string");
     33                               
     34                                writer.WriteRaw (jsonKeyValue);
     35                                writer.WriteString (value);
     36                               
     37                                writer.WriteEndObject ();
    2138                        }
    2239
     
    2441                                int value = gsi.GetValue ((GameInfoInt) Enum.Parse (typeof (GameInfoInt), intGamePref));
    2542
    26                                 JSONObject singleStat = new JSONObject ();
    27                                 singleStat.Add ("type", new JSONString ("int"));
    28                                 singleStat.Add ("value", new JSONNumber (value));
     43                                if (!first) {
     44                                        writer.WriteValueSeparator ();
     45                                }
    2946
    30                                 serverInfo.Add (intGamePref, singleStat);
     47                                first = false;
     48
     49                                writer.WritePropertyName (intGamePref);
     50                                writer.WriteRaw (jsonKeyType);
     51                                writer.WriteString ("int");
     52                               
     53                                writer.WriteRaw (jsonKeyValue);
     54                                writer.WriteInt32 (value);
     55                               
     56                                writer.WriteEndObject ();
    3157                        }
    3258
     
    3460                                bool value = gsi.GetValue ((GameInfoBool) Enum.Parse (typeof (GameInfoBool), boolGamePref));
    3561
    36                                 JSONObject singleStat = new JSONObject ();
    37                                 singleStat.Add ("type", new JSONString ("bool"));
    38                                 singleStat.Add ("value", new JSONBoolean (value));
     62                                if (!first) {
     63                                        writer.WriteValueSeparator ();
     64                                }
    3965
    40                                 serverInfo.Add (boolGamePref, singleStat);
     66                                first = false;
     67
     68                                writer.WritePropertyName (boolGamePref);
     69                                writer.WriteRaw (jsonKeyType);
     70                                writer.WriteString ("bool");
     71                               
     72                                writer.WriteRaw (jsonKeyValue);
     73                                writer.WriteBoolean (value);
     74                               
     75                                writer.WriteEndObject ();
    4176                        }
    42 
    43 
    44                         LegacyApiHelper.WriteJSON (_context.Response, serverInfo);
     77                       
     78                        writer.WriteEndObject ();
     79                       
     80                        WebUtils.WriteJsonData (_context.Response, ref writer);
    4581                }
    4682        }
  • binary-improvements/MapRendering/API/GetStats.cs

    r454 r455  
    1 using AllocsFixes.JSON;
    21using AllocsFixes.LiveData;
     2using JetBrains.Annotations;
     3using Utf8Json;
    34using Webserver;
    45using Webserver.WebAPI;
    56
    67namespace AllocsFixes.WebAPIs {
     8        [UsedImplicitly]
    79        public class GetStats : AbsWebAPI {
     10                private static readonly byte[] jsonKeyGameTime = JsonWriter.GetEncodedPropertyNameWithBeginObject ("gametime");
     11               
     12                private static readonly byte[] jsonKeyPlayers = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("players");
     13                private static readonly byte[] jsonKeyHostiles = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("hostiles");
     14                private static readonly byte[] jsonKeyAnimals = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("animals");
     15
    816                public override void HandleRequest (RequestContext _context) {
    9                         JSONObject result = new JSONObject ();
    10 
    11                         JSONObject time = new JSONObject ();
    12                         time.Add ("days", new JSONNumber (GameUtils.WorldTimeToDays (GameManager.Instance.World.worldTime)));
    13                         time.Add ("hours", new JSONNumber (GameUtils.WorldTimeToHours (GameManager.Instance.World.worldTime)));
    14                         time.Add ("minutes", new JSONNumber (GameUtils.WorldTimeToMinutes (GameManager.Instance.World.worldTime)));
    15                         result.Add ("gametime", time);
    16 
    17                         result.Add ("players", new JSONNumber (GameManager.Instance.World.Players.Count));
    18                         result.Add ("hostiles", new JSONNumber (Hostiles.Instance.GetCount ()));
    19                         result.Add ("animals", new JSONNumber (Animals.Instance.GetCount ()));
    20 
    21                         LegacyApiHelper.WriteJSON (_context.Response, result);
     17                        JsonWriter writer = new JsonWriter ();
     18       
     19                        writer.WriteRaw (jsonKeyGameTime);
     20                        (int days, int hours, int minutes) = GameUtils.WorldTimeToElements (GameManager.Instance.World.worldTime);
     21                        JsonCommons.WriteGameTimeObject (ref writer, days, hours, minutes);
     22                       
     23                        writer.WriteRaw (jsonKeyPlayers);
     24                        writer.WriteInt32 (GameManager.Instance.World.Players.Count);
     25                       
     26                        writer.WriteRaw (jsonKeyHostiles);
     27                        writer.WriteInt32 (Hostiles.Instance.GetCount ());
     28                       
     29                        writer.WriteRaw (jsonKeyAnimals);
     30                        writer.WriteInt32 (Animals.Instance.GetCount ());
     31                       
     32                        writer.WriteEndObject ();
     33                       
     34                        WebUtils.WriteJsonData (_context.Response, ref writer);
    2235                }
    2336
  • binary-improvements/MapRendering/API/GetWebUIUpdates.cs

    r454 r455  
    1 using AllocsFixes.JSON;
    21using AllocsFixes.LiveData;
     2using JetBrains.Annotations;
     3using Utf8Json;
    34using Webserver;
    45using Webserver.WebAPI;
    56
    67namespace AllocsFixes.WebAPIs {
     8        [UsedImplicitly]
    79        public class GetWebUIUpdates : AbsWebAPI {
     10                private static readonly byte[] jsonKeyGameTime = JsonWriter.GetEncodedPropertyNameWithBeginObject ("gametime");
     11               
     12                private static readonly byte[] jsonKeyPlayers = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("players");
     13                private static readonly byte[] jsonKeyHostiles = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("hostiles");
     14                private static readonly byte[] jsonKeyAnimals = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("animals");
     15                private static readonly byte[] jsonKeyNewLogs = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("newlogs");
     16
    817                public override void HandleRequest (RequestContext _context) {
    918                        int latestLine;
     
    1322                        }
    1423
    15                         JSONObject result = new JSONObject ();
     24                        JsonWriter writer = new JsonWriter ();
    1625
    17                         JSONObject time = new JSONObject ();
    18                         time.Add ("days", new JSONNumber (GameUtils.WorldTimeToDays (GameManager.Instance.World.worldTime)));
    19                         time.Add ("hours", new JSONNumber (GameUtils.WorldTimeToHours (GameManager.Instance.World.worldTime)));
    20                         time.Add ("minutes", new JSONNumber (GameUtils.WorldTimeToMinutes (GameManager.Instance.World.worldTime)));
    21                         result.Add ("gametime", time);
    22 
    23                         result.Add ("players", new JSONNumber (GameManager.Instance.World.Players.Count));
    24                         result.Add ("hostiles", new JSONNumber (Hostiles.Instance.GetCount ()));
    25                         result.Add ("animals", new JSONNumber (Animals.Instance.GetCount ()));
    26 
    27                         result.Add ("newlogs", new JSONNumber (LogBuffer.Instance.LatestLine - latestLine));
    28 
    29                         LegacyApiHelper.WriteJSON (_context.Response, result);
     26                        writer.WriteRaw (jsonKeyGameTime);
     27                        (int days, int hours, int minutes) = GameUtils.WorldTimeToElements (GameManager.Instance.World.worldTime);
     28                        JsonCommons.WriteGameTimeObject (ref writer, days, hours, minutes);
     29                       
     30                        writer.WriteRaw (jsonKeyPlayers);
     31                        writer.WriteInt32 (GameManager.Instance.World.Players.Count);
     32                       
     33                        writer.WriteRaw (jsonKeyHostiles);
     34                        writer.WriteInt32 (Hostiles.Instance.GetCount ());
     35                       
     36                        writer.WriteRaw (jsonKeyAnimals);
     37                        writer.WriteInt32 (Animals.Instance.GetCount ());
     38                       
     39                        writer.WriteRaw (jsonKeyNewLogs);
     40                        writer.WriteInt32 (LogBuffer.Instance.LatestLine - latestLine);
     41                       
     42                        writer.WriteEndObject ();
     43                       
     44                        WebUtils.WriteJsonData (_context.Response, ref writer);
    3045                }
    3146
  • binary-improvements/MapRendering/ModInfo.xml

    r454 r455  
    55                <Description value="Render the game map to image map tiles as it is uncovered" />
    66                <Author value="Christian 'Alloc' Illy" />
    7                 <Version value="43" />
    8                 <Website value="http://7dtd.illy.bz" />
     7                <Version value="44" />
     8                <Website value="https://7dtd.illy.bz" />
    99        </ModInfo>
    1010</xml>
  • binary-improvements/MapRendering/SteamLoginApi.cs

    r454 r455  
    1 using System;
    21using System.Net;
    3 using Platform.Steam;
     2using JetBrains.Annotations;
    43using Webserver;
    54using Webserver.UrlHandlers;
    65using Webserver.WebAPI;
    76
    8 namespace AllocsFixes {
     7namespace AllocsFixes.Web {
     8        [UsedImplicitly]
    99        public class SteamLoginApi : AbsWebAPI {
    1010                public override int DefaultPermissionLevel () => 2000;
     
    1515                private const string steamLoginUrl = "loginsteam";
    1616               
    17                 public SteamLoginApi (Web _parentWeb) : base(_parentWeb) {
     17                public SteamLoginApi (Webserver.Web _parentWeb) : base(_parentWeb) {
    1818                }
    1919
     
    4343                       
    4444                        if (subpath.StartsWith (steamLoginUrl)) {
    45                                 var absoluteUrl = _context.Request.Url.AbsolutePath;
     45                                string absoluteUrl = _context.Request.Url.AbsolutePath;
    4646                                absoluteUrl = absoluteUrl.Substring (0, absoluteUrl.Length - _context.RequestPath.Length);
    4747                                SessionHandler.HandleSteamLogin (_context, $"{absoluteUrl}{steamOpenIdVerifyUrl}");
  • binary-improvements/MapRendering/WebAndMapRendering.csproj

    r454 r455  
    8989      <Private>False</Private>
    9090    </Reference>
     91    <Reference Include="Utf8Json">
     92      <HintPath>..\7dtd-binaries\Utf8Json.dll</HintPath>
     93      <Private>False</Private>
     94    </Reference>
    9195    <Reference Include="WebServer, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
    9296      <HintPath>..\7dtd-binaries\WebServer.dll</HintPath>
     
    98102    <Compile Include="API\GetAllowedCommands.cs" />
    99103    <Compile Include="API\GetAnimalsLocation.cs" />
     104    <Compile Include="API\GetEntityListAbs.cs" />
    100105    <Compile Include="API\GetHostileLocation.cs" />
    101106    <Compile Include="API\GetLandClaims.cs" />
     
    111116    <Compile Include="AssemblyInfo.cs" />
    112117    <Compile Include="API.cs" />
    113     <Compile Include="LegacyApiHelper.cs" />
    114118    <Compile Include="SteamLoginApi.cs" />
    115119    <Compile Include="WebCommandResult.cs" />
  • binary-improvements/MapRendering/WebCommandResult.cs

    r454 r455  
    55using System.Text;
    66using System.Threading;
    7 using AllocsFixes.JSON;
    87using UnityEngine;
     8using Utf8Json;
    99using Webserver;
    1010
    11 namespace AllocsFixes.NetConnections.Servers.Web {
     11namespace AllocsFixes.Web {
    1212        public class WebCommandResult : IConsoleConnection {
    1313                public enum ResultType {
    1414                        Full,
    1515                        ResultOnly,
    16                         Raw
     16                        Raw,
    1717                }
    1818
     
    3535                        responseType = _resultType;
    3636                }
     37               
     38                private static readonly byte[] jsonKeyCommand = JsonWriter.GetEncodedPropertyNameWithBeginObject ("command");
     39                private static readonly byte[] jsonKeyParameters = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("parameters");
     40                private static readonly byte[] jsonKeyResult = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("result");
    3741
    3842                public void SendLines (List<string> _output) {
     
    4448                        }
    4549
     50                        string result = sb.ToString ();
     51
    4652                        try {
    4753                                context.Response.SendChunked = false;
    4854
    4955                                if (responseType == ResultType.Raw) {
    50                                         WebUtils.WriteText (context.Response, sb.ToString ());
     56                                        WebUtils.WriteText (context.Response, result);
    5157                                } else {
    52                                         JSONNode result;
     58                                        JsonWriter writer = new JsonWriter ();
     59
    5360                                        if (responseType == ResultType.ResultOnly) {
    54                                                 result = new JSONString (sb.ToString ());
     61                                                writer.WriteString (result);
    5562                                        } else {
    56                                                 JSONObject resultObj = new JSONObject ();
    57 
    58                                                 resultObj.Add ("command", new JSONString (command));
    59                                                 resultObj.Add ("parameters", new JSONString (parameters));
    60                                                 resultObj.Add ("result", new JSONString (sb.ToString ()));
    61 
    62                                                 result = resultObj;
     63                                                writer.WriteRaw (jsonKeyCommand);
     64                                                writer.WriteString (command);
     65                                               
     66                                                writer.WriteRaw (jsonKeyParameters);
     67                                                writer.WriteString (parameters);
     68                                               
     69                                                writer.WriteRaw (jsonKeyResult);
     70                                                writer.WriteString (result);
     71                                               
     72                                                writer.WriteEndObject ();
    6373                                        }
    6474
    65                                         LegacyApiHelper.WriteJSON (context.Response, result);
     75                                        WebUtils.WriteJsonData (context.Response, ref writer);
    6676                                }
    6777                        } catch (IOException e) {
    6878                                if (e.InnerException is SocketException) {
    69                                         Log.Out ("Error in WebCommandResult.SendLines(): Remote host closed connection: " + e.InnerException.Message);
     79                                        Log.Out ($"Error in WebCommandResult.SendLines(): Remote host closed connection: {e.InnerException.Message}");
    7080                                } else {
    71                                         Log.Out ("Error (IO) in WebCommandResult.SendLines(): " + e);
     81                                        Log.Out ($"Error (IO) in WebCommandResult.SendLines(): {e}");
    7282                                }
    7383                        } catch (Exception e) {
    74                                 Log.Out ("Error in WebCommandResult.SendLines(): " + e);
     84                                Log.Out ($"Error in WebCommandResult.SendLines(): {e}");
    7585                        } finally {
    7686                                context.Response?.Close ();
     
    99109
    100110                public string GetDescription () {
    101                         return "WebCommandResult_for_" + command;
     111                        return $"WebCommandResult_for_{command}";
    102112                }
    103113        }
  • binary-improvements/bin/Mods/Allocs_CommandExtensions/ModInfo.xml

    r446 r455  
    55                <Description value="Additional commands for server operation" />
    66                <Author value="Christian 'Alloc' Illy" />
    7                 <Version value="24" />
    8                 <Website value="http://7dtd.illy.bz" />
     7                <Version value="25" />
     8                <Website value="https://7dtd.illy.bz" />
    99        </ModInfo>
    1010</xml>
  • binary-improvements/bin/Mods/Allocs_CommonFunc/ModInfo.xml

    r448 r455  
    55                <Description value="Common functions" />
    66                <Author value="Christian 'Alloc' Illy" />
    7                 <Version value="29" />
    8                 <Website value="http://7dtd.illy.bz" />
     7                <Version value="30" />
     8                <Website value="https://7dtd.illy.bz" />
    99        </ModInfo>
    1010</xml>
  • binary-improvements/bin/Mods/Allocs_WebAndMapRendering/ModInfo.xml

    r454 r455  
    55                <Description value="Render the game map to image map tiles as it is uncovered" />
    66                <Author value="Christian 'Alloc' Illy" />
    7                 <Version value="43" />
    8                 <Website value="http://7dtd.illy.bz" />
     7                <Version value="44" />
     8                <Website value="https://7dtd.illy.bz" />
    99        </ModInfo>
    1010</xml>
Note: See TracChangeset for help on using the changeset viewer.