Ignore:
Timestamp:
Jan 27, 2023, 7:28:00 PM (22 months ago)
Author:
alloc
Message:
  • Major refactoring
  • Using Utf8Json for (de)serialization
  • Moving APIs to REST
  • Removing dependencies from WebServer and MapRenderer to ServerFixes
Location:
binary-improvements2/WebServer/src/WebAPI
Files:
3 added
2 deleted
1 edited
13 moved

Legend:

Unmodified
Added
Removed
  • binary-improvements2/WebServer/src/WebAPI/APIs/Animal.cs

    r401 r402  
    11using System.Collections.Generic;
    2 using AllocsFixes.JSON;
    3 using AllocsFixes.LiveData;
    42using JetBrains.Annotations;
     3using Utf8Json;
     4using Webserver.LiveData;
    55
    6 namespace Webserver.WebAPI {
     6namespace Webserver.WebAPI.APIs {
    77        [UsedImplicitly]
    8         internal class GetAnimalsLocation : AbsWebAPI {
    9                 private readonly List<EntityAnimal> animals = new List<EntityAnimal> ();
     8        internal class Animal : AbsRestApi {
     9                private readonly List<EntityAnimal> entities = new List<EntityAnimal> ();
    1010
    11                 public override void HandleRequest (RequestContext _context) {
    12                         JsonArray animalsJsResult = new JsonArray ();
     11                private static readonly byte[] jsonKeyId = JsonWriter.GetEncodedPropertyNameWithBeginObject ("id");
     12                private static readonly byte[] jsonKeyName = JsonWriter.GetEncodedPropertyNameWithBeginObject ("name");
     13                private static readonly byte[] jsonKeyPosition = JsonWriter.GetEncodedPropertyNameWithBeginObject ("position");
    1314
    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 ());
     15                protected override void HandleRestGet (RequestContext _context) {
     16                        PrepareEnvelopedResult (out JsonWriter writer);
     17                        writer.WriteBeginArray ();
     18                       
     19                        lock (entities) {
     20                                Animals.Instance.Get (entities);
     21                               
     22                                for (int i = 0; i < entities.Count; i++) {
     23                                        if (i > 0) {
     24                                                writer.WriteValueSeparator ();
     25                                        }
     26                                       
     27                                        EntityAlive entity = entities [i];
     28                                        Vector3i position = new Vector3i (entity.GetPosition ());
     29                                       
     30                                        writer.WriteRaw (jsonKeyId);
     31                                        writer.WriteInt32 (entity.entityId);
     32                                       
     33                                        writer.WriteRaw (jsonKeyName);
     34                                        writer.WriteString (!string.IsNullOrEmpty (entity.EntityName) ? entity.EntityName : $"animal class #{entity.entityClass}");
     35                                       
     36                                        writer.WriteRaw (jsonKeyPosition);
     37                                        JsonCommons.WritePositionObject (writer, position);
    1838
    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));
     39                                        writer.WriteEndObject ();
    3140                                }
    32 
    33                                 pJson.Add ("position", jsonPOS);
    34 
    35                                 animalsJsResult.Add (pJson);
    3641                        }
    37 
    38                         WebUtils.WriteJson (_context.Response, animalsJsResult);
     42                       
     43                        writer.WriteEndArray ();
     44                        SendEnvelopedResult (_context, ref writer);
    3945                }
    4046        }
  • binary-improvements2/WebServer/src/WebAPI/APIs/GetLandClaims.cs

    r401 r402  
    1 using System.Collections.Generic;
    2 using System.Net;
    3 using AllocsFixes;
    4 using AllocsFixes.JSON;
    5 using AllocsFixes.PersistentData;
    6 using JetBrains.Annotations;
    7 
    8 namespace Webserver.WebAPI {
    9         [UsedImplicitly]
    10         public class GetLandClaims : AbsWebAPI {
    11                 public override void HandleRequest (RequestContext _context) {
    12                         PlatformUserIdentifierAbs requestedUserId = null;
    13                         if (_context.Request.QueryString ["userid"] != null) {
    14                                 if (!PlatformUserIdentifierAbs.TryFromCombinedString (_context.Request.QueryString ["userid"], out requestedUserId)) {
    15                                         WebUtils.WriteText (_context.Response, "Invalid user id given", HttpStatusCode.BadRequest);
    16                                         return;
    17                                 }
    18                         }
    19 
    20                         // default user, cheap way to avoid 'null reference exception'
    21                         PlatformUserIdentifierAbs userId = _context.Connection?.UserId;
    22 
    23                         bool bViewAll = WebConnection.CanViewAllClaims (_context.PermissionLevel);
    24 
    25                         JsonObject result = new JsonObject ();
    26                         result.Add ("claimsize", new JsonNumber (GamePrefs.GetInt (EnumUtils.Parse<EnumGamePrefs> ("LandClaimSize"))));
    27 
    28                         JsonArray claimOwners = new JsonArray ();
    29                         result.Add ("claimowners", claimOwners);
    30 
    31                         LandClaimList.OwnerFilter[] ownerFilters = null;
    32                         if (requestedUserId != null || !bViewAll) {
    33                                 if (requestedUserId != null && !bViewAll) {
    34                                         ownerFilters = new[] {
    35                                                 LandClaimList.UserIdFilter (userId),
    36                                                 LandClaimList.UserIdFilter (requestedUserId)
    37                                         };
    38                                 } else if (!bViewAll) {
    39                                         ownerFilters = new[] {LandClaimList.UserIdFilter (userId)};
    40                                 } else {
    41                                         ownerFilters = new[] {LandClaimList.UserIdFilter (requestedUserId)};
    42                                 }
    43                         }
    44 
    45                         LandClaimList.PositionFilter[] posFilters = null;
    46 
    47                         Dictionary<Player, List<Vector3i>> claims = LandClaimList.GetLandClaims (ownerFilters, posFilters);
    48 
    49                         foreach ((Player player, List<Vector3i> claimPositions) in claims) {
    50                                 JsonObject owner = new JsonObject ();
    51                                 claimOwners.Add (owner);
    52 
    53                                 owner.Add ("steamid", new JsonString (player.PlatformId.CombinedString));
    54                                 owner.Add ("claimactive", new JsonBoolean (player.LandProtectionActive));
    55 
    56                                 if (player.Name.Length > 0) {
    57                                         owner.Add ("playername", new JsonString (player.Name));
    58                                 } else {
    59                                         owner.Add ("playername", new JsonNull ());
    60                                 }
    61 
    62                                 JsonArray claimsJson = new JsonArray ();
    63                                 owner.Add ("claims", claimsJson);
    64 
    65                                 foreach (Vector3i v in claimPositions) {
    66                                         JsonObject claim = new JsonObject ();
    67                                         claim.Add ("x", new JsonNumber (v.x));
    68                                         claim.Add ("y", new JsonNumber (v.y));
    69                                         claim.Add ("z", new JsonNumber (v.z));
    70 
    71                                         claimsJson.Add (claim);
    72                                 }
    73                         }
    74 
    75                         WebUtils.WriteJson (_context.Response, result);
    76                 }
    77         }
    78 }
     1// using System.Collections.Generic;
     2// using System.Net;
     3// using AllocsFixes;
     4// using AllocsFixes.PersistentData;
     5// using JetBrains.Annotations;
     6//
     7// namespace Webserver.WebAPI.APIs {
     8//      [UsedImplicitly]
     9//      public class GetLandClaims : AbsWebAPI {
     10//              public override void HandleRequest (RequestContext _context) {
     11//                      PlatformUserIdentifierAbs requestedUserId = null;
     12//                      if (_context.Request.QueryString ["userid"] != null) {
     13//                              if (!PlatformUserIdentifierAbs.TryFromCombinedString (_context.Request.QueryString ["userid"], out requestedUserId)) {
     14//                                      WebUtils.WriteText (_context.Response, "Invalid user id given", HttpStatusCode.BadRequest);
     15//                                      return;
     16//                              }
     17//                      }
     18//
     19//                      // default user, cheap way to avoid 'null reference exception'
     20//                      PlatformUserIdentifierAbs userId = _context.Connection?.UserId;
     21//
     22//                      bool bViewAll = WebConnection.CanViewAllClaims (_context.PermissionLevel);
     23//
     24//                      JsonObject result = new JsonObject ();
     25//                      result.Add ("claimsize",
     26//                              new JsonNumber (GamePrefs.GetInt (EnumUtils.Parse<EnumGamePrefs> (nameof (EnumGamePrefs.LandClaimSize)))));
     27//
     28//                      JsonArray claimOwners = new JsonArray ();
     29//                      result.Add ("claimowners", claimOwners);
     30//
     31//                      LandClaimList.OwnerFilter[] ownerFilters = null;
     32//                      if (requestedUserId != null || !bViewAll) {
     33//                              if (requestedUserId != null && !bViewAll) {
     34//                                      ownerFilters = new[] {
     35//                                              LandClaimList.UserIdFilter (userId),
     36//                                              LandClaimList.UserIdFilter (requestedUserId)
     37//                                      };
     38//                              } else if (!bViewAll) {
     39//                                      ownerFilters = new[] {LandClaimList.UserIdFilter (userId)};
     40//                              } else {
     41//                                      ownerFilters = new[] {LandClaimList.UserIdFilter (requestedUserId)};
     42//                              }
     43//                      }
     44//
     45//                      LandClaimList.PositionFilter[] posFilters = null;
     46//
     47//                      Dictionary<Player, List<Vector3i>> claims = LandClaimList.GetLandClaims (ownerFilters, posFilters);
     48//
     49//                      foreach ((Player player, List<Vector3i> claimPositions) in claims) {
     50//                              JsonObject owner = new JsonObject ();
     51//                              claimOwners.Add (owner);
     52//
     53//                              owner.Add ("steamid", new JsonString (player.PlatformId.CombinedString));
     54//                              owner.Add ("claimactive", new JsonBoolean (player.LandProtectionActive));
     55//
     56//                              if (player.Name.Length > 0) {
     57//                                      owner.Add ("playername", new JsonString (player.Name));
     58//                              } else {
     59//                                      owner.Add ("playername", new JsonNull ());
     60//                              }
     61//
     62//                              JsonArray claimsJson = new JsonArray ();
     63//                              owner.Add ("claims", claimsJson);
     64//
     65//                              foreach (Vector3i v in claimPositions) {
     66//                                      JsonObject claim = new JsonObject ();
     67//                                      claim.Add ("x", new JsonNumber (v.x));
     68//                                      claim.Add ("y", new JsonNumber (v.y));
     69//                                      claim.Add ("z", new JsonNumber (v.z));
     70//
     71//                                      claimsJson.Add (claim);
     72//                              }
     73//                      }
     74//
     75//                      WebUtils.WriteJson (_context.Response, result);
     76//              }
     77//      }
     78// }
  • binary-improvements2/WebServer/src/WebAPI/APIs/GetPlayerInventories.cs

    r401 r402  
    1 using System.Collections.Generic;
    2 using AllocsFixes.JSON;
    3 using AllocsFixes.PersistentData;
    4 using JetBrains.Annotations;
    5 
    6 namespace Webserver.WebAPI {
    7         [UsedImplicitly]
    8         public class GetPlayerInventories : AbsWebAPI {
    9                 public override void HandleRequest (RequestContext _context) {
    10                         GetPlayerInventory.GetInventoryArguments (_context.Request, out bool showIconColor, out bool showIconName);
    11 
    12                         JsonArray allInventoriesResult = new JsonArray ();
    13 
    14                         foreach ((PlatformUserIdentifierAbs userId, Player player) in PersistentContainer.Instance.Players.Dict) {
    15                                 if (player == null) {
    16                                         continue;
    17                                 }
    18 
    19                                 if (player.IsOnline) {
    20                                         allInventoriesResult.Add (GetPlayerInventory.DoPlayer (userId.CombinedString, player, showIconColor, showIconName));
    21                                 }
    22                         }
    23 
    24                         WebUtils.WriteJson (_context.Response, allInventoriesResult);
    25                 }
    26         }
    27 }
     1// using AllocsFixes.PersistentData;
     2// using JetBrains.Annotations;
     3//
     4// namespace Webserver.WebAPI.APIs {
     5//      [UsedImplicitly]
     6//      public class GetPlayerInventories : AbsWebAPI {
     7//              public override void HandleRequest (RequestContext _context) {
     8//                      GetPlayerInventory.GetInventoryArguments (_context.Request, out bool showIconColor, out bool showIconName);
     9//
     10//                      JsonArray allInventoriesResult = new JsonArray ();
     11//
     12//                      foreach ((PlatformUserIdentifierAbs userId, Player player) in PersistentContainer.Instance.Players.Dict) {
     13//                              if (player == null) {
     14//                                      continue;
     15//                              }
     16//
     17//                              if (player.IsOnline) {
     18//                                      allInventoriesResult.Add (GetPlayerInventory.DoPlayer (userId.CombinedString, player, showIconColor, showIconName));
     19//                              }
     20//                      }
     21//
     22//                      WebUtils.WriteJson (_context.Response, allInventoriesResult);
     23//              }
     24//      }
     25// }
  • binary-improvements2/WebServer/src/WebAPI/APIs/GetPlayerInventory.cs

    r401 r402  
    1 using System.Collections.Generic;
    2 using System.Net;
    3 using AllocsFixes.JSON;
    4 using AllocsFixes.PersistentData;
    5 using JetBrains.Annotations;
    6 using HttpListenerRequest = SpaceWizards.HttpListener.HttpListenerRequest;
    7 
    8 namespace Webserver.WebAPI {
    9         [UsedImplicitly]
    10         public class GetPlayerInventory : AbsWebAPI {
    11                 public override void HandleRequest (RequestContext _context) {
    12                         if (_context.Request.QueryString ["userid"] == null) {
    13                                 WebUtils.WriteText (_context.Response, "No user id given", HttpStatusCode.BadRequest);
    14                                 return;
    15                         }
    16 
    17                         string userIdString = _context.Request.QueryString ["userid"];
    18                         if (!PlatformUserIdentifierAbs.TryFromCombinedString (userIdString, out PlatformUserIdentifierAbs userId)) {
    19                                 WebUtils.WriteText (_context.Response, "Invalid user id given", HttpStatusCode.BadRequest);
    20                                 return;
    21                         }
    22 
    23                         Player p = PersistentContainer.Instance.Players [userId, false];
    24                         if (p == null) {
    25                                 WebUtils.WriteText (_context.Response, "Unknown user id given", HttpStatusCode.NotFound);
    26                                 return;
    27                         }
    28 
    29                         GetInventoryArguments (_context.Request, out bool showIconColor, out bool showIconName);
    30 
    31                         JsonObject result = DoPlayer (userIdString, p, showIconColor, showIconName);
    32 
    33                         WebUtils.WriteJson (_context.Response, result);
    34                 }
    35 
    36                 internal static void GetInventoryArguments (HttpListenerRequest _req, out bool _showIconColor, out bool _showIconName) {
    37                         if (_req.QueryString ["showiconcolor"] == null || !bool.TryParse (_req.QueryString ["showiconcolor"], out _showIconColor)) {
    38                                 _showIconColor = true;
    39                         }
    40                        
    41                         if (_req.QueryString ["showiconname"] == null || !bool.TryParse (_req.QueryString ["showiconname"], out _showIconName)) {
    42                                 _showIconName = true;
    43                         }
    44                 }
    45 
    46                 internal static JsonObject DoPlayer (string _steamId, Player _player, bool _showIconColor, bool _showIconName) {
    47                         AllocsFixes.PersistentData.Inventory inv = _player.Inventory;
    48 
    49                         JsonObject result = new JsonObject ();
    50 
    51                         JsonArray bag = new JsonArray ();
    52                         JsonArray belt = new JsonArray ();
    53                         JsonObject equipment = new JsonObject ();
    54                         result.Add ("userid", new JsonString (_steamId));
    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;
    79                 }
    80 
    81                 private static void DoInventory (JsonArray _jsonRes, List<InvItem> _inv, bool _showIconColor, bool _showIconName) {
    82                         for (int i = 0; i < _inv.Count; i++) {
    83                                 _jsonRes.Add (GetJsonForItem (_inv [i], _showIconColor, _showIconName));
    84                         }
    85                 }
    86 
    87                 private static void AddEquipment (JsonObject _eq, string _slotname, InvItem[] _items, EquipmentSlots _slot, bool _showIconColor, bool _showIconName) {
    88                         int[] slotindices = XUiM_PlayerEquipment.GetSlotIndicesByEquipmentSlot (_slot);
    89 
    90                         for (int i = 0; i < slotindices.Length; i++) {
    91                                 if (_items? [slotindices [i]] == null) {
    92                                         continue;
    93                                 }
    94 
    95                                 InvItem item = _items [slotindices [i]];
    96                                 _eq.Add (_slotname, GetJsonForItem (item, _showIconColor, _showIconName));
    97                                 return;
    98                         }
    99 
    100                         _eq.Add (_slotname, new JsonNull ());
    101                 }
    102 
    103                 private static JsonNode GetJsonForItem (InvItem _item, bool _showIconColor, bool _showIconName) {
    104                         if (_item == null) {
    105                                 return new JsonNull ();
    106                         }
    107 
    108                         JsonObject jsonItem = new JsonObject ();
    109                         jsonItem.Add ("count", new JsonNumber (_item.count));
    110                         jsonItem.Add ("name", new JsonString (_item.itemName));
    111                        
    112                         if (_showIconName) {
    113                                 jsonItem.Add ("icon", new JsonString (_item.icon));
    114                         }
    115 
    116                         if (_showIconColor) {
    117                                 jsonItem.Add ("iconcolor", new JsonString (_item.iconcolor));
    118                         }
    119 
    120                         jsonItem.Add ("quality", new JsonNumber (_item.quality));
    121                         if (_item.quality >= 0) {
    122                                 jsonItem.Add ("qualitycolor", new JsonString (QualityInfo.GetQualityColorHex (_item.quality)));
    123                         }
    124 
    125                         return jsonItem;
    126 
    127                 }
    128         }
    129 }
     1// using System.Collections.Generic;
     2// using System.Net;
     3// using AllocsFixes.PersistentData;
     4// using JetBrains.Annotations;
     5// using HttpListenerRequest = SpaceWizards.HttpListener.HttpListenerRequest;
     6//
     7// namespace Webserver.WebAPI.APIs {
     8//      [UsedImplicitly]
     9//      public class GetPlayerInventory : AbsWebAPI {
     10//              public override void HandleRequest (RequestContext _context) {
     11//                      if (_context.Request.QueryString ["userid"] == null) {
     12//                              WebUtils.WriteText (_context.Response, "No user id given", HttpStatusCode.BadRequest);
     13//                              return;
     14//                      }
     15//
     16//                      string userIdString = _context.Request.QueryString ["userid"];
     17//                      if (!PlatformUserIdentifierAbs.TryFromCombinedString (userIdString, out PlatformUserIdentifierAbs userId)) {
     18//                              WebUtils.WriteText (_context.Response, "Invalid user id given", HttpStatusCode.BadRequest);
     19//                              return;
     20//                      }
     21//
     22//                      Player p = PersistentContainer.Instance.Players [userId, false];
     23//                      if (p == null) {
     24//                              WebUtils.WriteText (_context.Response, "Unknown user id given", HttpStatusCode.NotFound);
     25//                              return;
     26//                      }
     27//
     28//                      GetInventoryArguments (_context.Request, out bool showIconColor, out bool showIconName);
     29//
     30//                      JsonObject result = DoPlayer (userIdString, p, showIconColor, showIconName);
     31//
     32//                      WebUtils.WriteJson (_context.Response, result);
     33//              }
     34//
     35//              internal static void GetInventoryArguments (HttpListenerRequest _req, out bool _showIconColor, out bool _showIconName) {
     36//                      if (_req.QueryString ["showiconcolor"] == null || !bool.TryParse (_req.QueryString ["showiconcolor"], out _showIconColor)) {
     37//                              _showIconColor = true;
     38//                      }
     39//                     
     40//                      if (_req.QueryString ["showiconname"] == null || !bool.TryParse (_req.QueryString ["showiconname"], out _showIconName)) {
     41//                              _showIconName = true;
     42//                      }
     43//              }
     44//
     45//              internal static JsonObject DoPlayer (string _steamId, Player _player, bool _showIconColor, bool _showIconName) {
     46//                      AllocsFixes.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 (_steamId));
     54//                      result.Add ("entityid", new JsonNumber (_player.EntityID));
     55//                      result.Add ("playername", new JsonString (_player.Name));
     56//                      result.Add ("bag", bag);
     57//                      result.Add ("belt", belt);
     58//                      result.Add ("equipment", equipment);
     59//
     60//                      DoInventory (belt, inv.belt, _showIconColor, _showIconName);
     61//                      DoInventory (bag, inv.bag, _showIconColor, _showIconName);
     62//
     63//                      AddEquipment (equipment, "head", inv.equipment, EquipmentSlots.Headgear, _showIconColor, _showIconName);
     64//                      AddEquipment (equipment, "eyes", inv.equipment, EquipmentSlots.Eyewear, _showIconColor, _showIconName);
     65//                      AddEquipment (equipment, "face", inv.equipment, EquipmentSlots.Face, _showIconColor, _showIconName);
     66//
     67//                      AddEquipment (equipment, "armor", inv.equipment, EquipmentSlots.ChestArmor, _showIconColor, _showIconName);
     68//                      AddEquipment (equipment, "jacket", inv.equipment, EquipmentSlots.Jacket, _showIconColor, _showIconName);
     69//                      AddEquipment (equipment, "shirt", inv.equipment, EquipmentSlots.Shirt, _showIconColor, _showIconName);
     70//
     71//                      AddEquipment (equipment, "legarmor", inv.equipment, EquipmentSlots.LegArmor, _showIconColor, _showIconName);
     72//                      AddEquipment (equipment, "pants", inv.equipment, EquipmentSlots.Legs, _showIconColor, _showIconName);
     73//                      AddEquipment (equipment, "boots", inv.equipment, EquipmentSlots.Feet, _showIconColor, _showIconName);
     74//
     75//                      AddEquipment (equipment, "gloves", inv.equipment, EquipmentSlots.Hands, _showIconColor, _showIconName);
     76//
     77//                      return result;
     78//              }
     79//
     80//              private static void DoInventory (JsonArray _jsonRes, List<InvItem> _inv, bool _showIconColor, bool _showIconName) {
     81//                      for (int i = 0; i < _inv.Count; i++) {
     82//                              _jsonRes.Add (GetJsonForItem (_inv [i], _showIconColor, _showIconName));
     83//                      }
     84//              }
     85//
     86//              private static void AddEquipment (JsonObject _eq, string _slotname, InvItem[] _items, EquipmentSlots _slot, bool _showIconColor, bool _showIconName) {
     87//                      int[] slotindices = XUiM_PlayerEquipment.GetSlotIndicesByEquipmentSlot (_slot);
     88//
     89//                      for (int i = 0; i < slotindices.Length; i++) {
     90//                              if (_items? [slotindices [i]] == null) {
     91//                                      continue;
     92//                              }
     93//
     94//                              InvItem item = _items [slotindices [i]];
     95//                              _eq.Add (_slotname, GetJsonForItem (item, _showIconColor, _showIconName));
     96//                              return;
     97//                      }
     98//
     99//                      _eq.Add (_slotname, new JsonNull ());
     100//              }
     101//
     102//              private static JsonNode GetJsonForItem (InvItem _item, bool _showIconColor, bool _showIconName) {
     103//                      if (_item == null) {
     104//                              return new JsonNull ();
     105//                      }
     106//
     107//                      JsonObject jsonItem = new JsonObject ();
     108//                      jsonItem.Add ("count", new JsonNumber (_item.count));
     109//                      jsonItem.Add ("name", new JsonString (_item.itemName));
     110//                     
     111//                      if (_showIconName) {
     112//                              jsonItem.Add ("icon", new JsonString (_item.icon));
     113//                      }
     114//
     115//                      if (_showIconColor) {
     116//                              jsonItem.Add ("iconcolor", new JsonString (_item.iconcolor));
     117//                      }
     118//
     119//                      jsonItem.Add ("quality", new JsonNumber (_item.quality));
     120//                      if (_item.quality >= 0) {
     121//                              jsonItem.Add ("qualitycolor", new JsonString (QualityInfo.GetQualityColorHex (_item.quality)));
     122//                      }
     123//
     124//                      return jsonItem;
     125//
     126//              }
     127//      }
     128// }
  • binary-improvements2/WebServer/src/WebAPI/APIs/GetPlayerList.cs

    r401 r402  
    1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text.RegularExpressions;
    5 using AllocsFixes.JSON;
    6 using AllocsFixes.PersistentData;
    7 using JetBrains.Annotations;
    8 
    9 namespace Webserver.WebAPI {
    10         [UsedImplicitly]
    11         public class GetPlayerList : AbsWebAPI {
    12                 private static readonly Regex numberFilterMatcher =
    13                         new Regex (@"^(>=|=>|>|<=|=<|<|==|=)?\s*([0-9]+(\.[0-9]*)?)$");
    14 
    15                 private static readonly UnityEngine.Profiling.CustomSampler jsonSerializeSampler = UnityEngine.Profiling.CustomSampler.Create ("JSON_Build");
    16 
    17                 public override void HandleRequest (RequestContext _context) {
    18                         AdminTools admTools = GameManager.Instance.adminTools;
    19                         PlatformUserIdentifierAbs userId = _context.Connection?.UserId;
    20 
    21                         bool bViewAll = WebConnection.CanViewAllPlayers (_context.PermissionLevel);
    22 
    23                         // TODO: Sort (and filter?) prior to converting to JSON ... hard as how to get the correct column's data? (i.e. column name matches JSON object field names, not source data)
    24 
    25                         int rowsPerPage = 25;
    26                         if (_context.Request.QueryString ["rowsperpage"] != null) {
    27                                 int.TryParse (_context.Request.QueryString ["rowsperpage"], out rowsPerPage);
    28                         }
    29 
    30                         int page = 0;
    31                         if (_context.Request.QueryString ["page"] != null) {
    32                                 int.TryParse (_context.Request.QueryString ["page"], out page);
    33                         }
    34 
    35                         int firstEntry = page * rowsPerPage;
    36 
    37                         Players playersList = PersistentContainer.Instance.Players;
    38 
    39                        
    40                         List<JsonObject> playerList = new List<JsonObject> ();
    41 
    42                         jsonSerializeSampler.Begin ();
    43 
    44                         foreach (KeyValuePair<PlatformUserIdentifierAbs, Player> kvp in playersList.Dict) {
    45                                 Player p = kvp.Value;
    46 
    47                                 if (bViewAll || p.PlatformId.Equals (userId)) {
    48                                         JsonObject pos = new JsonObject ();
    49                                         pos.Add ("x", new JsonNumber (p.LastPosition.x));
    50                                         pos.Add ("y", new JsonNumber (p.LastPosition.y));
    51                                         pos.Add ("z", new JsonNumber (p.LastPosition.z));
    52 
    53                                         JsonObject pJson = new JsonObject ();
    54                                         pJson.Add ("steamid", new JsonString (kvp.Key.CombinedString));
    55                                         pJson.Add ("entityid", new JsonNumber (p.EntityID));
    56                                         pJson.Add ("ip", new JsonString (p.IP));
    57                                         pJson.Add ("name", new JsonString (p.Name));
    58                                         pJson.Add ("online", new JsonBoolean (p.IsOnline));
    59                                         pJson.Add ("position", pos);
    60 
    61                                         pJson.Add ("totalplaytime", new JsonNumber (p.TotalPlayTime));
    62                                         pJson.Add ("lastonline",
    63                                                 new JsonString (p.LastOnline.ToUniversalTime ().ToString ("yyyy-MM-ddTHH:mm:ssZ")));
    64                                         pJson.Add ("ping", new JsonNumber (p.IsOnline ? p.ClientInfo.ping : -1));
    65 
    66                                         JsonBoolean banned = admTools != null ? new JsonBoolean (admTools.IsBanned (kvp.Key, out _, out _)) : new JsonBoolean (false);
    67 
    68                                         pJson.Add ("banned", banned);
    69 
    70                                         playerList.Add (pJson);
    71                                 }
    72                         }
    73 
    74                         jsonSerializeSampler.End ();
    75 
    76                         IEnumerable<JsonObject> list = playerList;
    77 
    78                         foreach (string key in _context.Request.QueryString.AllKeys) {
    79                                 if (!string.IsNullOrEmpty (key) && key.StartsWith ("filter[")) {
    80                                         string filterCol = key.Substring (key.IndexOf ('[') + 1);
    81                                         filterCol = filterCol.Substring (0, filterCol.Length - 1);
    82                                         string filterVal = _context.Request.QueryString.Get (key).Trim ();
    83 
    84                                         list = ExecuteFilter (list, filterCol, filterVal);
    85                                 }
    86                         }
    87 
    88                         int totalAfterFilter = list.Count ();
    89 
    90                         foreach (string key in _context.Request.QueryString.AllKeys) {
    91                                 if (!string.IsNullOrEmpty (key) && key.StartsWith ("sort[")) {
    92                                         string sortCol = key.Substring (key.IndexOf ('[') + 1);
    93                                         sortCol = sortCol.Substring (0, sortCol.Length - 1);
    94                                         string sortVal = _context.Request.QueryString.Get (key);
    95 
    96                                         list = ExecuteSort (list, sortCol, sortVal == "0");
    97                                 }
    98                         }
    99 
    100                         list = list.Skip (firstEntry);
    101                         list = list.Take (rowsPerPage);
    102 
    103 
    104                         JsonArray playersJsResult = new JsonArray ();
    105                         foreach (JsonObject jsO in list) {
    106                                 playersJsResult.Add (jsO);
    107                         }
    108 
    109                         JsonObject result = new JsonObject ();
    110                         result.Add ("total", new JsonNumber (totalAfterFilter));
    111                         result.Add ("totalUnfiltered", new JsonNumber (playerList.Count));
    112                         result.Add ("firstResult", new JsonNumber (firstEntry));
    113                         result.Add ("players", playersJsResult);
    114 
    115                         WebUtils.WriteJson (_context.Response, result);
    116                 }
    117 
    118                 private IEnumerable<JsonObject> ExecuteFilter (IEnumerable<JsonObject> _list, string _filterCol,
    119                         string _filterVal) {
    120                         if (!_list.Any()) {
    121                                 return _list;
    122                         }
    123 
    124                         if (_list.First ().ContainsKey (_filterCol)) {
    125                                 Type colType = _list.First () [_filterCol].GetType ();
    126                                 if (colType == typeof (JsonNumber)) {
    127                                         return ExecuteNumberFilter (_list, _filterCol, _filterVal);
    128                                 }
    129 
    130                                 if (colType == typeof (JsonBoolean)) {
    131                                         bool value = StringParsers.ParseBool (_filterVal);
    132                                         return _list.Where (_line => ((JsonBoolean) _line [_filterCol]).GetBool () == value);
    133                                 }
    134 
    135                                 if (colType == typeof (JsonString)) {
    136                                         // regex-match whole ^string$, replace * by .*, ? by .?, + by .+
    137                                         _filterVal = _filterVal.Replace ("*", ".*").Replace ("?", ".?").Replace ("+", ".+");
    138                                         _filterVal = "^" + _filterVal + "$";
    139 
    140                                         //Log.Out ("GetPlayerList: Filter on String with Regex '" + _filterVal + "'");
    141                                         Regex matcher = new Regex (_filterVal, RegexOptions.IgnoreCase);
    142                                         return _list.Where (_line => matcher.IsMatch (((JsonString) _line [_filterCol]).GetString ()));
    143                                 }
    144                         }
    145 
    146                         return _list;
    147                 }
    148 
    149 
    150                 private IEnumerable<JsonObject> ExecuteNumberFilter (IEnumerable<JsonObject> _list, string _filterCol,
    151                         string _filterVal) {
    152                         // allow value (exact match), =, ==, >=, >, <=, <
    153                         Match filterMatch = numberFilterMatcher.Match (_filterVal);
    154                         if (filterMatch.Success) {
    155                                 double value = StringParsers.ParseDouble (filterMatch.Groups [2].Value);
    156                                 NumberMatchType matchType;
    157                                 double epsilon = value / 100000;
    158                                 switch (filterMatch.Groups [1].Value) {
    159                                         case "":
    160                                         case "=":
    161                                         case "==":
    162                                                 matchType = NumberMatchType.Equal;
    163                                                 break;
    164                                         case ">":
    165                                                 matchType = NumberMatchType.Greater;
    166                                                 break;
    167                                         case ">=":
    168                                         case "=>":
    169                                                 matchType = NumberMatchType.GreaterEqual;
    170                                                 break;
    171                                         case "<":
    172                                                 matchType = NumberMatchType.Lesser;
    173                                                 break;
    174                                         case "<=":
    175                                         case "=<":
    176                                                 matchType = NumberMatchType.LesserEqual;
    177                                                 break;
    178                                         default:
    179                                                 matchType = NumberMatchType.Equal;
    180                                                 break;
    181                                 }
    182 
    183                                 return _list.Where (delegate (JsonObject _line) {
    184                                         double objVal = ((JsonNumber) _line [_filterCol]).GetDouble ();
    185                                         switch (matchType) {
    186                                                 case NumberMatchType.Greater:
    187                                                         return objVal > value;
    188                                                 case NumberMatchType.GreaterEqual:
    189                                                         return objVal >= value;
    190                                                 case NumberMatchType.Lesser:
    191                                                         return objVal < value;
    192                                                 case NumberMatchType.LesserEqual:
    193                                                         return objVal <= value;
    194                                                 case NumberMatchType.Equal:
    195                                                 default:
    196                                                         return NearlyEqual (objVal, value, epsilon);
    197                                         }
    198                                 });
    199                         }
    200 
    201                         Log.Out ("[Web] GetPlayerList: ignoring invalid filter for number-column '{0}': '{1}'", _filterCol, _filterVal);
    202                         return _list;
    203                 }
    204 
    205 
    206                 private IEnumerable<JsonObject> ExecuteSort (IEnumerable<JsonObject> _list, string _sortCol, bool _ascending) {
    207                         if (_list.Count () == 0) {
    208                                 return _list;
    209                         }
    210 
    211                         if (_list.First ().ContainsKey (_sortCol)) {
    212                                 Type colType = _list.First () [_sortCol].GetType ();
    213                                 if (colType == typeof (JsonNumber)) {
    214                                         if (_ascending) {
    215                                                 return _list.OrderBy (_line => ((JsonNumber) _line [_sortCol]).GetDouble ());
    216                                         }
    217 
    218                                         return _list.OrderByDescending (_line => ((JsonNumber) _line [_sortCol]).GetDouble ());
    219                                 }
    220 
    221                                 if (colType == typeof (JsonBoolean)) {
    222                                         if (_ascending) {
    223                                                 return _list.OrderBy (_line => ((JsonBoolean) _line [_sortCol]).GetBool ());
    224                                         }
    225 
    226                                         return _list.OrderByDescending (_line => ((JsonBoolean) _line [_sortCol]).GetBool ());
    227                                 }
    228 
    229                                 if (_ascending) {
    230                                         return _list.OrderBy (_line => _line [_sortCol].ToString ());
    231                                 }
    232 
    233                                 return _list.OrderByDescending (_line => _line [_sortCol].ToString ());
    234                         }
    235 
    236                         return _list;
    237                 }
    238 
    239 
    240                 private bool NearlyEqual (double _a, double _b, double _epsilon) {
    241                         double absA = Math.Abs (_a);
    242                         double absB = Math.Abs (_b);
    243                         double diff = Math.Abs (_a - _b);
    244 
    245                         if (_a == _b) {
    246                                 return true;
    247                         }
    248 
    249                         if (_a == 0 || _b == 0 || diff < double.Epsilon) {
    250                                 return diff < _epsilon;
    251                         }
    252 
    253                         return diff / (absA + absB) < _epsilon;
    254                 }
    255 
    256                 private enum NumberMatchType {
    257                         Equal,
    258                         Greater,
    259                         GreaterEqual,
    260                         Lesser,
    261                         LesserEqual
    262                 }
    263         }
    264 }
     1// using System;
     2// using System.Collections.Generic;
     3// using System.Linq;
     4// using System.Text.RegularExpressions;
     5// using AllocsFixes.PersistentData;
     6// using JetBrains.Annotations;
     7//
     8// namespace Webserver.WebAPI.APIs {
     9//      [UsedImplicitly]
     10//      public class GetPlayerList : AbsWebAPI {
     11//              private static readonly Regex numberFilterMatcher =
     12//                      new Regex (@"^(>=|=>|>|<=|=<|<|==|=)?\s*([0-9]+(\.[0-9]*)?)$");
     13//
     14//              private static readonly UnityEngine.Profiling.CustomSampler jsonSerializeSampler = UnityEngine.Profiling.CustomSampler.Create ("JSON_Build");
     15//
     16//              public override void HandleRequest (RequestContext _context) {
     17//                      AdminTools admTools = GameManager.Instance.adminTools;
     18//                      PlatformUserIdentifierAbs userId = _context.Connection?.UserId;
     19//
     20//                      bool bViewAll = WebConnection.CanViewAllPlayers (_context.PermissionLevel);
     21//
     22//                      // TODO: Sort (and filter?) prior to converting to JSON ... hard as how to get the correct column's data? (i.e. column name matches JSON object field names, not source data)
     23//
     24//                      int rowsPerPage = 25;
     25//                      if (_context.Request.QueryString ["rowsperpage"] != null) {
     26//                              int.TryParse (_context.Request.QueryString ["rowsperpage"], out rowsPerPage);
     27//                      }
     28//
     29//                      int page = 0;
     30//                      if (_context.Request.QueryString ["page"] != null) {
     31//                              int.TryParse (_context.Request.QueryString ["page"], out page);
     32//                      }
     33//
     34//                      int firstEntry = page * rowsPerPage;
     35//
     36//                      Players playersList = PersistentContainer.Instance.Players;
     37//
     38//                     
     39//                      List<JsonObject> playerList = new List<JsonObject> ();
     40//
     41//                      jsonSerializeSampler.Begin ();
     42//
     43//                      foreach (KeyValuePair<PlatformUserIdentifierAbs, Player> kvp in playersList.Dict) {
     44//                              Player p = kvp.Value;
     45//
     46//                              if (bViewAll || p.PlatformId.Equals (userId)) {
     47//                                      JsonObject pos = new JsonObject ();
     48//                                      pos.Add ("x", new JsonNumber (p.LastPosition.x));
     49//                                      pos.Add ("y", new JsonNumber (p.LastPosition.y));
     50//                                      pos.Add ("z", new JsonNumber (p.LastPosition.z));
     51//
     52//                                      JsonObject pJson = new JsonObject ();
     53//                                      pJson.Add ("steamid", new JsonString (kvp.Key.CombinedString));
     54//                                      pJson.Add ("entityid", new JsonNumber (p.EntityID));
     55//                                      pJson.Add ("ip", new JsonString (p.IP));
     56//                                      pJson.Add ("name", new JsonString (p.Name));
     57//                                      pJson.Add ("online", new JsonBoolean (p.IsOnline));
     58//                                      pJson.Add ("position", pos);
     59//
     60//                                      pJson.Add ("totalplaytime", new JsonNumber (p.TotalPlayTime));
     61//                                      pJson.Add ("lastonline",
     62//                                              new JsonString (p.LastOnline.ToUniversalTime ().ToString ("yyyy-MM-ddTHH:mm:ssZ")));
     63//                                      pJson.Add ("ping", new JsonNumber (p.IsOnline ? p.ClientInfo.ping : -1));
     64//
     65//                                      JsonBoolean banned = admTools != null ? new JsonBoolean (admTools.IsBanned (kvp.Key, out _, out _)) : new JsonBoolean (false);
     66//
     67//                                      pJson.Add ("banned", banned);
     68//
     69//                                      playerList.Add (pJson);
     70//                              }
     71//                      }
     72//
     73//                      jsonSerializeSampler.End ();
     74//
     75//                      IEnumerable<JsonObject> list = playerList;
     76//
     77//                      foreach (string key in _context.Request.QueryString.AllKeys) {
     78//                              if (!string.IsNullOrEmpty (key) && key.StartsWith ("filter[")) {
     79//                                      string filterCol = key.Substring (key.IndexOf ('[') + 1);
     80//                                      filterCol = filterCol.Substring (0, filterCol.Length - 1);
     81//                                      string filterVal = _context.Request.QueryString.Get (key).Trim ();
     82//
     83//                                      list = ExecuteFilter (list, filterCol, filterVal);
     84//                              }
     85//                      }
     86//
     87//                      int totalAfterFilter = list.Count ();
     88//
     89//                      foreach (string key in _context.Request.QueryString.AllKeys) {
     90//                              if (!string.IsNullOrEmpty (key) && key.StartsWith ("sort[")) {
     91//                                      string sortCol = key.Substring (key.IndexOf ('[') + 1);
     92//                                      sortCol = sortCol.Substring (0, sortCol.Length - 1);
     93//                                      string sortVal = _context.Request.QueryString.Get (key);
     94//
     95//                                      list = ExecuteSort (list, sortCol, sortVal == "0");
     96//                              }
     97//                      }
     98//
     99//                      list = list.Skip (firstEntry);
     100//                      list = list.Take (rowsPerPage);
     101//
     102//
     103//                      JsonArray playersJsResult = new JsonArray ();
     104//                      foreach (JsonObject jsO in list) {
     105//                              playersJsResult.Add (jsO);
     106//                      }
     107//
     108//                      JsonObject result = new JsonObject ();
     109//                      result.Add ("total", new JsonNumber (totalAfterFilter));
     110//                      result.Add ("totalUnfiltered", new JsonNumber (playerList.Count));
     111//                      result.Add ("firstResult", new JsonNumber (firstEntry));
     112//                      result.Add ("players", playersJsResult);
     113//
     114//                      WebUtils.WriteJson (_context.Response, result);
     115//              }
     116//
     117//              private IEnumerable<JsonObject> ExecuteFilter (IEnumerable<JsonObject> _list, string _filterCol,
     118//                      string _filterVal) {
     119//                      if (!_list.Any()) {
     120//                              return _list;
     121//                      }
     122//
     123//                      if (_list.First ().ContainsKey (_filterCol)) {
     124//                              Type colType = _list.First () [_filterCol].GetType ();
     125//                              if (colType == typeof (JsonNumber)) {
     126//                                      return ExecuteNumberFilter (_list, _filterCol, _filterVal);
     127//                              }
     128//
     129//                              if (colType == typeof (JsonBoolean)) {
     130//                                      bool value = StringParsers.ParseBool (_filterVal);
     131//                                      return _list.Where (_line => ((JsonBoolean) _line [_filterCol]).GetBool () == value);
     132//                              }
     133//
     134//                              if (colType == typeof (JsonString)) {
     135//                                      // regex-match whole ^string$, replace * by .*, ? by .?, + by .+
     136//                                      _filterVal = _filterVal.Replace ("*", ".*").Replace ("?", ".?").Replace ("+", ".+");
     137//                                      _filterVal = "^" + _filterVal + "$";
     138//
     139//                                      //Log.Out ("GetPlayerList: Filter on String with Regex '" + _filterVal + "'");
     140//                                      Regex matcher = new Regex (_filterVal, RegexOptions.IgnoreCase);
     141//                                      return _list.Where (_line => matcher.IsMatch (((JsonString) _line [_filterCol]).GetString ()));
     142//                              }
     143//                      }
     144//
     145//                      return _list;
     146//              }
     147//
     148//
     149//              private IEnumerable<JsonObject> ExecuteNumberFilter (IEnumerable<JsonObject> _list, string _filterCol,
     150//                      string _filterVal) {
     151//                      // allow value (exact match), =, ==, >=, >, <=, <
     152//                      Match filterMatch = numberFilterMatcher.Match (_filterVal);
     153//                      if (filterMatch.Success) {
     154//                              double value = StringParsers.ParseDouble (filterMatch.Groups [2].Value);
     155//                              NumberMatchType matchType;
     156//                              double epsilon = value / 100000;
     157//                              switch (filterMatch.Groups [1].Value) {
     158//                                      case "":
     159//                                      case "=":
     160//                                      case "==":
     161//                                              matchType = NumberMatchType.Equal;
     162//                                              break;
     163//                                      case ">":
     164//                                              matchType = NumberMatchType.Greater;
     165//                                              break;
     166//                                      case ">=":
     167//                                      case "=>":
     168//                                              matchType = NumberMatchType.GreaterEqual;
     169//                                              break;
     170//                                      case "<":
     171//                                              matchType = NumberMatchType.Lesser;
     172//                                              break;
     173//                                      case "<=":
     174//                                      case "=<":
     175//                                              matchType = NumberMatchType.LesserEqual;
     176//                                              break;
     177//                                      default:
     178//                                              matchType = NumberMatchType.Equal;
     179//                                              break;
     180//                              }
     181//
     182//                              return _list.Where (delegate (JsonObject _line) {
     183//                                      double objVal = ((JsonNumber) _line [_filterCol]).GetDouble ();
     184//                                      switch (matchType) {
     185//                                              case NumberMatchType.Greater:
     186//                                                      return objVal > value;
     187//                                              case NumberMatchType.GreaterEqual:
     188//                                                      return objVal >= value;
     189//                                              case NumberMatchType.Lesser:
     190//                                                      return objVal < value;
     191//                                              case NumberMatchType.LesserEqual:
     192//                                                      return objVal <= value;
     193//                                              case NumberMatchType.Equal:
     194//                                              default:
     195//                                                      return NearlyEqual (objVal, value, epsilon);
     196//                                      }
     197//                              });
     198//                      }
     199//
     200//                      global::Log.Out ("[Web] GetPlayerList: ignoring invalid filter for number-column '{0}': '{1}'", _filterCol, _filterVal);
     201//                      return _list;
     202//              }
     203//
     204//
     205//              private IEnumerable<JsonObject> ExecuteSort (IEnumerable<JsonObject> _list, string _sortCol, bool _ascending) {
     206//                      if (_list.Count () == 0) {
     207//                              return _list;
     208//                      }
     209//
     210//                      if (_list.First ().ContainsKey (_sortCol)) {
     211//                              Type colType = _list.First () [_sortCol].GetType ();
     212//                              if (colType == typeof (JsonNumber)) {
     213//                                      if (_ascending) {
     214//                                              return _list.OrderBy (_line => ((JsonNumber) _line [_sortCol]).GetDouble ());
     215//                                      }
     216//
     217//                                      return _list.OrderByDescending (_line => ((JsonNumber) _line [_sortCol]).GetDouble ());
     218//                              }
     219//
     220//                              if (colType == typeof (JsonBoolean)) {
     221//                                      if (_ascending) {
     222//                                              return _list.OrderBy (_line => ((JsonBoolean) _line [_sortCol]).GetBool ());
     223//                                      }
     224//
     225//                                      return _list.OrderByDescending (_line => ((JsonBoolean) _line [_sortCol]).GetBool ());
     226//                              }
     227//
     228//                              if (_ascending) {
     229//                                      return _list.OrderBy (_line => _line [_sortCol].ToString ());
     230//                              }
     231//
     232//                              return _list.OrderByDescending (_line => _line [_sortCol].ToString ());
     233//                      }
     234//
     235//                      return _list;
     236//              }
     237//
     238//
     239//              private bool NearlyEqual (double _a, double _b, double _epsilon) {
     240//                      double absA = Math.Abs (_a);
     241//                      double absB = Math.Abs (_b);
     242//                      double diff = Math.Abs (_a - _b);
     243//
     244//                      if (_a == _b) {
     245//                              return true;
     246//                      }
     247//
     248//                      if (_a == 0 || _b == 0 || diff < double.Epsilon) {
     249//                              return diff < _epsilon;
     250//                      }
     251//
     252//                      return diff / (absA + absB) < _epsilon;
     253//              }
     254//
     255//              private enum NumberMatchType {
     256//                      Equal,
     257//                      Greater,
     258//                      GreaterEqual,
     259//                      Lesser,
     260//                      LesserEqual
     261//              }
     262//      }
     263// }
  • binary-improvements2/WebServer/src/WebAPI/APIs/GetPlayersLocation.cs

    r401 r402  
    1 using System.Collections.Generic;
    2 using AllocsFixes.JSON;
    3 using AllocsFixes.PersistentData;
    4 using JetBrains.Annotations;
    5 
    6 namespace Webserver.WebAPI {
    7         [UsedImplicitly]
    8         public class GetPlayersLocation : AbsWebAPI {
    9                 public override void HandleRequest (RequestContext _context) {
    10                         AdminTools admTools = GameManager.Instance.adminTools;
    11                         PlatformUserIdentifierAbs reqUserId = _context.Connection?.UserId;
    12 
    13                         bool listOffline = false;
    14                         if (_context.Request.QueryString ["offline"] != null) {
    15                                 bool.TryParse (_context.Request.QueryString ["offline"], out listOffline);
    16                         }
    17 
    18                         bool bViewAll = WebConnection.CanViewAllPlayers (_context.PermissionLevel);
    19 
    20                         JsonArray playersJsResult = new JsonArray ();
    21 
    22                         Players playersList = PersistentContainer.Instance.Players;
    23 
    24                         foreach ((PlatformUserIdentifierAbs userId, Player player) in playersList.Dict) {
    25                                 if (admTools != null) {
    26                                         if (admTools.IsBanned (userId, out _, out _)) {
    27                                                 continue;
    28                                         }
    29                                 }
    30 
    31                                 if (!listOffline && !player.IsOnline) {
    32                                         continue;
    33                                 }
    34 
    35                                 if (!bViewAll && !player.PlatformId.Equals (reqUserId)) {
    36                                         continue;
    37                                 }
    38 
    39                                 JsonObject pos = new JsonObject ();
    40                                 pos.Add ("x", new JsonNumber (player.LastPosition.x));
    41                                 pos.Add ("y", new JsonNumber (player.LastPosition.y));
    42                                 pos.Add ("z", new JsonNumber (player.LastPosition.z));
    43 
    44                                 JsonObject pJson = new JsonObject ();
    45                                 pJson.Add ("steamid", new JsonString (userId.CombinedString));
    46 
    47                                 //                                      pJson.Add("entityid", new JSONNumber (p.EntityID));
    48                                 //                    pJson.Add("ip", new JSONString (p.IP));
    49                                 pJson.Add ("name", new JsonString (player.Name));
    50                                 pJson.Add ("online", new JsonBoolean (player.IsOnline));
    51                                 pJson.Add ("position", pos);
    52 
    53                                 //                                      pJson.Add ("totalplaytime", new JSONNumber (p.TotalPlayTime));
    54                                 //                                      pJson.Add ("lastonline", new JSONString (p.LastOnline.ToString ("s")));
    55                                 //                                      pJson.Add ("ping", new JSONNumber (p.IsOnline ? p.ClientInfo.ping : -1));
    56 
    57                                 playersJsResult.Add (pJson);
    58                         }
    59 
    60                         WebUtils.WriteJson (_context.Response, playersJsResult);
    61                 }
    62         }
    63 }
     1// using AllocsFixes.PersistentData;
     2// using JetBrains.Annotations;
     3//
     4// namespace Webserver.WebAPI.APIs {
     5//      [UsedImplicitly]
     6//      public class GetPlayersLocation : AbsWebAPI {
     7//              public override void HandleRequest (RequestContext _context) {
     8//                      AdminTools admTools = GameManager.Instance.adminTools;
     9//                      PlatformUserIdentifierAbs reqUserId = _context.Connection?.UserId;
     10//
     11//                      bool listOffline = false;
     12//                      if (_context.Request.QueryString ["offline"] != null) {
     13//                              bool.TryParse (_context.Request.QueryString ["offline"], out listOffline);
     14//                      }
     15//
     16//                      bool bViewAll = WebConnection.CanViewAllPlayers (_context.PermissionLevel);
     17//
     18//                      JsonArray playersJsResult = new JsonArray ();
     19//
     20//                      Players playersList = PersistentContainer.Instance.Players;
     21//
     22//                      foreach ((PlatformUserIdentifierAbs userId, Player player) in playersList.Dict) {
     23//                              if (admTools != null) {
     24//                                      if (admTools.IsBanned (userId, out _, out _)) {
     25//                                              continue;
     26//                                      }
     27//                              }
     28//
     29//                              if (!listOffline && !player.IsOnline) {
     30//                                      continue;
     31//                              }
     32//
     33//                              if (!bViewAll && !player.PlatformId.Equals (reqUserId)) {
     34//                                      continue;
     35//                              }
     36//
     37//                              JsonObject pos = new JsonObject ();
     38//                              pos.Add ("x", new JsonNumber (player.LastPosition.x));
     39//                              pos.Add ("y", new JsonNumber (player.LastPosition.y));
     40//                              pos.Add ("z", new JsonNumber (player.LastPosition.z));
     41//
     42//                              JsonObject pJson = new JsonObject ();
     43//                              pJson.Add ("steamid", new JsonString (userId.CombinedString));
     44//
     45//                              //                                      pJson.Add("entityid", new JSONNumber (p.EntityID));
     46//                              //                    pJson.Add("ip", new JSONString (p.IP));
     47//                              pJson.Add ("name", new JsonString (player.Name));
     48//                              pJson.Add ("online", new JsonBoolean (player.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);
     56//                      }
     57//
     58//                      WebUtils.WriteJson (_context.Response, playersJsResult);
     59//              }
     60//      }
     61// }
  • binary-improvements2/WebServer/src/WebAPI/APIs/GetPlayersOnline.cs

    r401 r402  
    1 using System.Collections.Generic;
    2 using AllocsFixes.JSON;
    3 using AllocsFixes.PersistentData;
    4 using JetBrains.Annotations;
    5 
    6 namespace Webserver.WebAPI {
    7         [UsedImplicitly]
    8         public class GetPlayersOnline : AbsWebAPI {
    9                 public override void HandleRequest (RequestContext _context) {
    10                         JsonArray players = new JsonArray ();
    11 
    12                         World w = GameManager.Instance.World;
    13                         foreach ((int entityId, EntityPlayer entityPlayer) in w.Players.dict) {
    14                                 ClientInfo ci = ConnectionManager.Instance.Clients.ForEntityId (entityId);
    15                                 Player player = PersistentContainer.Instance.Players [ci.InternalId, false];
    16 
    17                                 JsonObject pos = new JsonObject ();
    18                                 pos.Add ("x", new JsonNumber ((int) entityPlayer.GetPosition ().x));
    19                                 pos.Add ("y", new JsonNumber ((int) entityPlayer.GetPosition ().y));
    20                                 pos.Add ("z", new JsonNumber ((int) entityPlayer.GetPosition ().z));
    21 
    22                                 JsonObject p = new JsonObject ();
    23                                 p.Add ("steamid", new JsonString (ci.PlatformId.CombinedString));
    24                                 p.Add ("entityid", new JsonNumber (ci.entityId));
    25                                 p.Add ("ip", new JsonString (ci.ip));
    26                                 p.Add ("name", new JsonString (entityPlayer.EntityName));
    27                                 p.Add ("online", new JsonBoolean (true));
    28                                 p.Add ("position", pos);
    29 
    30                                 p.Add ("level", new JsonNumber (player?.Level ?? -1));
    31                                 p.Add ("health", new JsonNumber (entityPlayer.Health));
    32                                 p.Add ("stamina", new JsonNumber (entityPlayer.Stamina));
    33                                 p.Add ("zombiekills", new JsonNumber (entityPlayer.KilledZombies));
    34                                 p.Add ("playerkills", new JsonNumber (entityPlayer.KilledPlayers));
    35                                 p.Add ("playerdeaths", new JsonNumber (entityPlayer.Died));
    36                                 p.Add ("score", new JsonNumber (entityPlayer.Score));
    37 
    38                                 p.Add ("totalplaytime", new JsonNumber (player?.TotalPlayTime ?? -1));
    39                                 p.Add ("lastonline", new JsonString (player != null ? player.LastOnline.ToString ("s") : string.Empty));
    40                                 p.Add ("ping", new JsonNumber (ci.ping));
    41 
    42                                 players.Add (p);
    43                         }
    44 
    45                         WebUtils.WriteJson (_context.Response, players);
    46                 }
    47         }
    48 }
     1// using AllocsFixes.PersistentData;
     2// using JetBrains.Annotations;
     3//
     4// namespace Webserver.WebAPI.APIs {
     5//      [UsedImplicitly]
     6//      public class GetPlayersOnline : AbsWebAPI {
     7//              public override void HandleRequest (RequestContext _context) {
     8//                      JsonArray players = new JsonArray ();
     9//
     10//                      World w = GameManager.Instance.World;
     11//                      foreach ((int entityId, EntityPlayer entityPlayer) in w.Players.dict) {
     12//                              ClientInfo ci = ConnectionManager.Instance.Clients.ForEntityId (entityId);
     13//                              Player player = PersistentContainer.Instance.Players [ci.InternalId, false];
     14//
     15//                              JsonObject pos = new JsonObject ();
     16//                              pos.Add ("x", new JsonNumber ((int) entityPlayer.GetPosition ().x));
     17//                              pos.Add ("y", new JsonNumber ((int) entityPlayer.GetPosition ().y));
     18//                              pos.Add ("z", new JsonNumber ((int) entityPlayer.GetPosition ().z));
     19//
     20//                              JsonObject p = new JsonObject ();
     21//                              p.Add ("steamid", new JsonString (ci.PlatformId.CombinedString));
     22//                              p.Add ("entityid", new JsonNumber (ci.entityId));
     23//                              p.Add ("ip", new JsonString (ci.ip));
     24//                              p.Add ("name", new JsonString (entityPlayer.EntityName));
     25//                              p.Add ("online", new JsonBoolean (true));
     26//                              p.Add ("position", pos);
     27//
     28//                              p.Add ("level", new JsonNumber (player?.Level ?? -1));
     29//                              p.Add ("health", new JsonNumber (entityPlayer.Health));
     30//                              p.Add ("stamina", new JsonNumber (entityPlayer.Stamina));
     31//                              p.Add ("zombiekills", new JsonNumber (entityPlayer.KilledZombies));
     32//                              p.Add ("playerkills", new JsonNumber (entityPlayer.KilledPlayers));
     33//                              p.Add ("playerdeaths", new JsonNumber (entityPlayer.Died));
     34//                              p.Add ("score", new JsonNumber (entityPlayer.Score));
     35//
     36//                              p.Add ("totalplaytime", new JsonNumber (player?.TotalPlayTime ?? -1));
     37//                              p.Add ("lastonline", new JsonString (player != null ? player.LastOnline.ToString ("s") : string.Empty));
     38//                              p.Add ("ping", new JsonNumber (ci.ping));
     39//
     40//                              players.Add (p);
     41//                      }
     42//
     43//                      WebUtils.WriteJson (_context.Response, players);
     44//              }
     45//      }
     46// }
  • binary-improvements2/WebServer/src/WebAPI/APIs/Hostile.cs

    r401 r402  
    11using System.Collections.Generic;
    2 using AllocsFixes.JSON;
    3 using AllocsFixes.LiveData;
    42using JetBrains.Annotations;
     3using Utf8Json;
     4using Webserver.LiveData;
    55
    6 namespace Webserver.WebAPI {
     6namespace Webserver.WebAPI.APIs {
    77        [UsedImplicitly]
    8         internal class GetHostileLocation : AbsWebAPI {
    9                 private readonly List<EntityEnemy> enemies = new List<EntityEnemy> ();
     8        internal class Hostile : AbsRestApi {
     9                private readonly List<EntityEnemy> entities = new List<EntityEnemy> ();
    1010
    11                 public override void HandleRequest (RequestContext _context) {
    12                         JsonArray hostilesJsResult = new JsonArray ();
     11                private static readonly byte[] jsonKeyId = JsonWriter.GetEncodedPropertyNameWithBeginObject ("id");
     12                private static readonly byte[] jsonKeyName = JsonWriter.GetEncodedPropertyNameWithBeginObject ("name");
     13                private static readonly byte[] jsonKeyPosition = JsonWriter.GetEncodedPropertyNameWithBeginObject ("position");
    1314
    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 ());
     15                protected override void HandleRestGet (RequestContext _context) {
     16                        PrepareEnvelopedResult (out JsonWriter writer);
     17                        writer.WriteBeginArray ();
     18                       
     19                        lock (entities) {
     20                                Hostiles.Instance.Get (entities);
     21                               
     22                                for (int i = 0; i < entities.Count; i++) {
     23                                        if (i > 0) {
     24                                                writer.WriteValueSeparator ();
     25                                        }
     26                                       
     27                                        EntityAlive entity = entities [i];
     28                                        Vector3i position = new Vector3i (entity.GetPosition ());
     29                                       
     30                                        writer.WriteRaw (jsonKeyId);
     31                                        writer.WriteInt32 (entity.entityId);
     32                                       
     33                                        writer.WriteRaw (jsonKeyName);
     34                                        writer.WriteString (!string.IsNullOrEmpty (entity.EntityName) ? entity.EntityName : $"enemy class #{entity.entityClass}");
     35                                       
     36                                        writer.WriteRaw (jsonKeyPosition);
     37                                        JsonCommons.WritePositionObject (writer, position);
    1838
    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));
     39                                        writer.WriteEndObject ();
    3140                                }
    32 
    33                                 pJson.Add ("position", jsonPOS);
    34 
    35                                 hostilesJsResult.Add (pJson);
    3641                        }
    37 
    38                         WebUtils.WriteJson (_context.Response, hostilesJsResult);
     42                       
     43                        writer.WriteEndArray ();
     44                        SendEnvelopedResult (_context, ref writer);
    3945                }
    4046        }
  • binary-improvements2/WebServer/src/WebAPI/APIs/Log.cs

    r401 r402  
    11using System.Collections.Generic;
    2 using AllocsFixes.JSON;
    32using JetBrains.Annotations;
     3using Utf8Json;
    44
    5 namespace Webserver.WebAPI {
     5namespace Webserver.WebAPI.APIs {
    66        [UsedImplicitly]
    7         public class GetLog : AbsWebAPI {
    8                 private const int MAX_COUNT = 1000;
     7        public class Log : AbsRestApi {
     8                private const int maxCount = 1000;
     9
     10                private static readonly byte[] jsonKeyEntries = JsonWriter.GetEncodedPropertyNameWithBeginObject ("entries");
     11                private static readonly byte[] jsonKeyFirstLine = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("firstLine");
     12                private static readonly byte[] jsonKeyLastLine = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("lastLine");
     13
     14                private static readonly byte[] jsonMsgKey = JsonWriter.GetEncodedPropertyNameWithBeginObject ("msg");
     15                private static readonly byte[] jsonTypeKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("type");
     16                private static readonly byte[] jsonTraceKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("trace");
     17                private static readonly byte[] jsonIsotimeKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("isotime");
     18                private static readonly byte[] jsonUptimeKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("uptime");
    919               
    10                 public override void HandleRequest (RequestContext _context) {
     20                protected override void HandleRestGet (RequestContext _context) {
    1121                        if (_context.Request.QueryString ["count"] == null || !int.TryParse (_context.Request.QueryString ["count"], out int count)) {
    1222                                count = 50;
     
    1727                        }
    1828
    19                         if (count > MAX_COUNT) {
    20                                 count = MAX_COUNT;
     29                        if (count > maxCount) {
     30                                count = maxCount;
    2131                        }
    2232
    23                         if (count < -MAX_COUNT) {
    24                                 count = -MAX_COUNT;
     33                        if (count < -maxCount) {
     34                                count = -maxCount;
    2535                        }
    2636
     
    2838                                firstLine = count > 0 ? LogBuffer.Instance.OldestLine : LogBuffer.Instance.LatestLine;
    2939                        }
    30 
    31                         JsonObject result = new JsonObject ();
    32 
     40                       
     41                        PrepareEnvelopedResult (out JsonWriter writer);
     42                       
     43                        writer.WriteRaw (jsonKeyEntries);
     44                       
    3345                        List<LogBuffer.LogEntry> logEntries = LogBuffer.Instance.GetRange (ref firstLine, count, out int lastLine);
    3446
    35                         JsonArray entries = new JsonArray ();
     47                        writer.WriteBeginArray ();
     48
     49                        bool first = true;
    3650                        foreach (LogBuffer.LogEntry logEntry in logEntries) {
    37                                 JsonObject entry = new JsonObject ();
    38                                 entry.Add ("isotime", new JsonString (logEntry.isoTime));
    39                                 entry.Add ("uptime", new JsonString (logEntry.uptime.ToString ()));
    40                                 entry.Add ("msg", new JsonString (logEntry.message));
    41                                 entry.Add ("trace", new JsonString (logEntry.trace));
    42                                 entry.Add ("type", new JsonString (logEntry.type.ToStringCached ()));
    43                                 entries.Add (entry);
     51                                if (!first) {
     52                                        writer.WriteValueSeparator ();
     53                                }
     54
     55                                first = false;
     56                               
     57                                writer.WriteRaw (jsonMsgKey);
     58                                writer.WriteString (logEntry.message);
     59                               
     60                                writer.WriteRaw (jsonTypeKey);
     61                                writer.WriteString (logEntry.type.ToStringCached ());
     62                               
     63                                writer.WriteRaw (jsonTraceKey);
     64                                writer.WriteString (logEntry.trace);
     65                               
     66                                writer.WriteRaw (jsonIsotimeKey);
     67                                writer.WriteString (logEntry.isoTime);
     68                               
     69                                writer.WriteRaw (jsonUptimeKey);
     70                                writer.WriteString (logEntry.uptime.ToString ());
     71                               
     72                                writer.WriteEndObject ();
    4473                        }
     74                        writer.WriteEndArray ();
    4575
    46                         result.Add ("firstLine", new JsonNumber (firstLine));
    47                         result.Add ("lastLine", new JsonNumber (lastLine));
    48                         result.Add ("entries", entries);
     76                        writer.WriteRaw (jsonKeyFirstLine);
     77                        writer.WriteInt32 (firstLine);
     78                       
     79                        writer.WriteRaw (jsonKeyLastLine);
     80                        writer.WriteInt32 (lastLine);
     81                       
     82                        writer.WriteEndObject ();
    4983
    50                         WebUtils.WriteJson (_context.Response, result);
     84                        SendEnvelopedResult (_context, ref writer);
    5185                }
    5286        }
  • binary-improvements2/WebServer/src/WebAPI/APIs/ServerInfo.cs

    r401 r402  
    1 using System;
    2 using AllocsFixes.JSON;
    31using JetBrains.Annotations;
     2using Utf8Json;
    43
    5 namespace Webserver.WebAPI {
     4namespace Webserver.WebAPI.APIs {
    65        [UsedImplicitly]
    7         public class GetServerInfo : AbsWebAPI {
    8                 public override void HandleRequest (RequestContext _context) {
    9                         JsonObject serverInfo = new JsonObject ();
     6        public class ServerInfo : AbsRestApi {
     7                private static readonly UnityEngine.Profiling.CustomSampler buildSampler = UnityEngine.Profiling.CustomSampler.Create ("JSON_ServerInfo_BuildSampler");
    108
     9                private static readonly byte[] keyType = JsonWriter.GetEncodedPropertyNameWithBeginObject ("type");
     10                private static readonly byte[] keyValue = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("value");
     11
     12                private int largestBuffer;
     13
     14                protected override void HandleRestGet (RequestContext _context) {
     15                        buildSampler.Begin ();
     16
     17                        PrepareEnvelopedResult (out JsonWriter writer);
     18                       
     19                        writer.EnsureCapacity (largestBuffer);
     20                        writer.WriteBeginObject ();
     21                       
    1122                        GameServerInfo gsi = ConnectionManager.Instance.LocalServerInfo;
    1223
    13                         foreach (string stringGamePref in Enum.GetNames (typeof (GameInfoString))) {
    14                                 string value = gsi.GetValue ((GameInfoString) Enum.Parse (typeof (GameInfoString), stringGamePref));
     24                        bool first = true;
     25                       
     26                       
    1527
    16                                 JsonObject singleStat = new JsonObject ();
    17                                 singleStat.Add ("type", new JsonString ("string"));
    18                                 singleStat.Add ("value", new JsonString (value));
     28                        foreach (GameInfoString stringGamePref in EnumUtils.Values<GameInfoString> ()) {
     29                                string value = gsi.GetValue (stringGamePref);
    1930
    20                                 serverInfo.Add (stringGamePref, singleStat);
     31                                if (!first) {
     32                                        writer.WriteValueSeparator ();
     33                                }
     34
     35                                first = false;
     36                               
     37                                writer.WriteString (stringGamePref.ToStringCached ());
     38                                writer.WriteNameSeparator ();
     39                               
     40                                writer.WriteRaw (keyType);
     41                                writer.WriteString ("string");
     42                               
     43                                writer.WriteRaw (keyValue);
     44                                writer.WriteString (value);
     45                               
     46                                writer.WriteEndObject ();
    2147                        }
    2248
    23                         foreach (string intGamePref in Enum.GetNames (typeof (GameInfoInt))) {
    24                                 int value = gsi.GetValue ((GameInfoInt) Enum.Parse (typeof (GameInfoInt), intGamePref));
     49                        foreach (GameInfoInt intGamePref in EnumUtils.Values<GameInfoInt> ()) {
     50                                int value = gsi.GetValue (intGamePref);
    2551
    26                                 JsonObject singleStat = new JsonObject ();
    27                                 singleStat.Add ("type", new JsonString ("int"));
    28                                 singleStat.Add ("value", new JsonNumber (value));
     52                                if (!first) {
     53                                        writer.WriteValueSeparator ();
     54                                }
    2955
    30                                 serverInfo.Add (intGamePref, singleStat);
     56                                first = false;
     57                               
     58                                writer.WriteString (intGamePref.ToStringCached ());
     59                                writer.WriteNameSeparator ();
     60                               
     61                                writer.WriteRaw (keyType);
     62                                writer.WriteString ("int");
     63                               
     64                                writer.WriteRaw (keyValue);
     65                                writer.WriteInt32 (value);
     66                               
     67                                writer.WriteEndObject ();
    3168                        }
    3269
    33                         foreach (string boolGamePref in Enum.GetNames (typeof (GameInfoBool))) {
    34                                 bool value = gsi.GetValue ((GameInfoBool) Enum.Parse (typeof (GameInfoBool), boolGamePref));
     70                        foreach (GameInfoBool boolGamePref in EnumUtils.Values<GameInfoBool> ()) {
     71                                bool value = gsi.GetValue (boolGamePref);
    3572
    36                                 JsonObject singleStat = new JsonObject ();
    37                                 singleStat.Add ("type", new JsonString ("bool"));
    38                                 singleStat.Add ("value", new JsonBoolean (value));
     73                                if (!first) {
     74                                        writer.WriteValueSeparator ();
     75                                }
    3976
    40                                 serverInfo.Add (boolGamePref, singleStat);
     77                                first = false;
     78                               
     79                                writer.WriteString (boolGamePref.ToStringCached ());
     80                                writer.WriteNameSeparator ();
     81                               
     82                                writer.WriteRaw (keyType);
     83                                writer.WriteString ("bool");
     84                               
     85                                writer.WriteRaw (keyValue);
     86                                writer.WriteBoolean (value);
     87                               
     88                                writer.WriteEndObject ();
    4189                        }
     90                       
     91                        writer.WriteEndObject ();
     92                       
     93                        buildSampler.End ();
    4294
    43 
    44                         WebUtils.WriteJson (_context.Response, serverInfo);
     95                        int bufferContentSize = writer.CurrentOffset + 128;
     96                        if (bufferContentSize > largestBuffer) {
     97                                largestBuffer = bufferContentSize;
     98                        }
     99                       
     100                        SendEnvelopedResult (_context, ref writer);
    45101                }
    46102        }
  • binary-improvements2/WebServer/src/WebAPI/APIs/ServerStats.cs

    r401 r402  
    1 using AllocsFixes.JSON;
    2 using AllocsFixes.LiveData;
    31using JetBrains.Annotations;
     2using Utf8Json;
     3using Webserver.LiveData;
    44
    5 namespace Webserver.WebAPI {
     5namespace Webserver.WebAPI.APIs {
    66        [UsedImplicitly]
    7         public class GetStats : AbsWebAPI {
    8                 public override void HandleRequest (RequestContext _context) {
    9                         JsonObject result = new JsonObject ();
     7        public class ServerStats : AbsRestApi {
     8                private static readonly byte[] jsonKeyGameTime = JsonWriter.GetEncodedPropertyNameWithBeginObject ("gameTime");
     9                private static readonly byte[] jsonKeyPlayers = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("players");
     10                private static readonly byte[] jsonKeyHostiles = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("hostiles");
     11                private static readonly byte[] jsonKeyAnimals = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("animals");
     12               
     13                private static readonly byte[] jsonKeyDays = JsonWriter.GetEncodedPropertyNameWithBeginObject ("days");
     14                private static readonly byte[] jsonKeyHours = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("hours");
     15                private static readonly byte[] jsonKeyMinutes = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("minutes");
    1016
    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);
     17                protected override void HandleRestGet (RequestContext _context) {
     18                        PrepareEnvelopedResult (out JsonWriter writer);
     19                       
     20                        writer.WriteRaw (jsonKeyGameTime);
    1621
    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 ()));
     22                        (int days, int hours, int minutes) = GameUtils.WorldTimeToElements (GameManager.Instance.World.worldTime);
     23                       
     24                        writer.WriteRaw (jsonKeyDays);
     25                        writer.WriteInt32 (days);
     26                       
     27                        writer.WriteRaw (jsonKeyHours);
     28                        writer.WriteInt32 (hours);
     29                       
     30                        writer.WriteRaw (jsonKeyMinutes);
     31                        writer.WriteInt32 (minutes);
     32                       
     33                        writer.WriteEndObject ();
    2034
    21                         WebUtils.WriteJson (_context.Response, result);
     35                        writer.WriteRaw (jsonKeyPlayers);
     36                        writer.WriteInt32 (GameManager.Instance.World.Players.Count);
     37                       
     38                        writer.WriteRaw (jsonKeyHostiles);
     39                        writer.WriteInt32 (Hostiles.Instance.GetCount ());
     40                       
     41                        writer.WriteRaw (jsonKeyAnimals);
     42                        writer.WriteInt32 (Animals.Instance.GetCount ());
     43                       
     44                        writer.WriteEndObject ();
     45
     46                        SendEnvelopedResult (_context, ref writer);
    2247                }
    2348
  • binary-improvements2/WebServer/src/WebAPI/APIs/WebMods.cs

    r401 r402  
    1 using AllocsFixes.JSON;
    21using JetBrains.Annotations;
     2using Utf8Json;
    33
    4 namespace Webserver.WebAPI {
     4namespace Webserver.WebAPI.APIs {
    55        [UsedImplicitly]
    6         public class GetWebMods : AbsWebAPI {
    7                 private readonly JsonArray loadedWebMods = new JsonArray ();
     6        public class WebMods : AbsRestApi {
     7                private readonly byte[] loadedWebMods;
    88
    9                 public GetWebMods (Web _parent) {
     9                public WebMods (Web _parent) {
     10                        JsonWriter writer = new JsonWriter ();
     11                        writer.WriteBeginArray ();
     12
     13                        bool first = true;
    1014                        foreach (WebMod webMod in _parent.webMods) {
    11                                 JsonObject modJson = new JsonObject ();
     15                                if (!first) {
     16                                        writer.WriteValueSeparator ();
     17                                }
     18                                first = false;
     19                               
     20                                writer.WriteBeginObject ();
     21                               
     22                                writer.WriteString ("name");
     23                                writer.WriteNameSeparator ();
     24                                writer.WriteString (webMod.ParentMod.Name);
    1225
    13                                 modJson.Add ("name", new JsonString (webMod.ParentMod.ModInfo.Name.Value));
    14                                
    1526                                string webModReactBundle = webMod.ReactBundle;
    1627                                if (webModReactBundle != null) {
    17                                         modJson.Add ("bundle", new JsonString (webModReactBundle));
     28                                        writer.WriteValueSeparator ();
     29                                        writer.WriteString ("bundle");
     30                                        writer.WriteNameSeparator ();
     31                                        writer.WriteString (webModReactBundle);
    1832                                }
    19 
     33                               
    2034                                string webModCssFile = webMod.CssPath;
    2135                                if (webModCssFile != null) {
    22                                         modJson.Add ("css", new JsonString (webModCssFile));
     36                                        writer.WriteValueSeparator ();
     37                                        writer.WriteString ("css");
     38                                        writer.WriteNameSeparator ();
     39                                        writer.WriteString (webModCssFile);
    2340                                }
     41                               
     42                                writer.WriteEndObject ();
     43                        }
     44                       
     45                        writer.WriteEndArray ();
    2446
    25                                 loadedWebMods.Add (modJson);
    26                         }
     47                        loadedWebMods = writer.ToUtf8ByteArray ();
    2748                }
    2849
    29                 public override void HandleRequest (RequestContext _context) {
    30                         WebUtils.WriteJson (_context.Response, loadedWebMods);
     50                protected override void HandleRestGet (RequestContext _context) {
     51                        PrepareEnvelopedResult (out JsonWriter writer);
     52                        writer.WriteRaw (loadedWebMods);
     53                        SendEnvelopedResult (_context, ref writer);
    3154                }
    3255
  • binary-improvements2/WebServer/src/WebAPI/APIs/WebUiUpdates.cs

    r401 r402  
    1 using AllocsFixes.JSON;
    2 using AllocsFixes.LiveData;
    31using JetBrains.Annotations;
     2using Utf8Json;
     3using Webserver.LiveData;
    44
    5 namespace Webserver.WebAPI {
     5namespace Webserver.WebAPI.APIs {
    66        [UsedImplicitly]
    7         public class GetWebUIUpdates : AbsWebAPI {
    8                 public override void HandleRequest (RequestContext _context) {
     7        public class WebUiUpdates : AbsRestApi {
     8                private static readonly byte[] jsonKeyGameTime = JsonWriter.GetEncodedPropertyNameWithBeginObject ("gameTime");
     9                private static readonly byte[] jsonKeyPlayers = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("players");
     10                private static readonly byte[] jsonKeyHostiles = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("hostiles");
     11                private static readonly byte[] jsonKeyAnimals = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("animals");
     12                private static readonly byte[] jsonKeyNewLogs = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("newLogs");
     13               
     14                private static readonly byte[] jsonKeyDays = JsonWriter.GetEncodedPropertyNameWithBeginObject ("days");
     15                private static readonly byte[] jsonKeyHours = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("hours");
     16                private static readonly byte[] jsonKeyMinutes = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("minutes");
     17
     18               
     19                protected override void HandleRestGet (RequestContext _context) {
    920                        if (_context.Request.QueryString ["latestLine"] == null ||
    1021                            !int.TryParse (_context.Request.QueryString ["latestLine"], out int latestLine)) {
    1122                                latestLine = 0;
    1223                        }
     24                       
     25                        PrepareEnvelopedResult (out JsonWriter writer);
     26                       
     27                        writer.WriteRaw (jsonKeyGameTime);
    1328
    14                         JsonObject result = new JsonObject ();
     29                        (int days, int hours, int minutes) = GameUtils.WorldTimeToElements (GameManager.Instance.World.worldTime);
     30                       
     31                        writer.WriteRaw (jsonKeyDays);
     32                        writer.WriteInt32 (days);
     33                       
     34                        writer.WriteRaw (jsonKeyHours);
     35                        writer.WriteInt32 (hours);
     36                       
     37                        writer.WriteRaw (jsonKeyMinutes);
     38                        writer.WriteInt32 (minutes);
     39                       
     40                        writer.WriteEndObject ();
    1541
    16                         JsonObject time = new JsonObject ();
    17                         time.Add ("days", new JsonNumber (GameUtils.WorldTimeToDays (GameManager.Instance.World.worldTime)));
    18                         time.Add ("hours", new JsonNumber (GameUtils.WorldTimeToHours (GameManager.Instance.World.worldTime)));
    19                         time.Add ("minutes", new JsonNumber (GameUtils.WorldTimeToMinutes (GameManager.Instance.World.worldTime)));
    20                         result.Add ("gametime", time);
     42                        writer.WriteRaw (jsonKeyPlayers);
     43                        writer.WriteInt32 (GameManager.Instance.World.Players.Count);
     44                       
     45                        writer.WriteRaw (jsonKeyHostiles);
     46                        writer.WriteInt32 (Hostiles.Instance.GetCount ());
     47                       
     48                        writer.WriteRaw (jsonKeyAnimals);
     49                        writer.WriteInt32 (Animals.Instance.GetCount ());
     50                       
     51                        writer.WriteRaw (jsonKeyNewLogs);
     52                        writer.WriteInt32 (LogBuffer.Instance.LatestLine - latestLine);
    2153
    22                         result.Add ("players", new JsonNumber (GameManager.Instance.World.Players.Count));
    23                         result.Add ("hostiles", new JsonNumber (Hostiles.Instance.GetCount ()));
    24                         result.Add ("animals", new JsonNumber (Animals.Instance.GetCount ()));
     54                        writer.WriteEndObject ();
    2555
    26                         result.Add ("newlogs", new JsonNumber (LogBuffer.Instance.LatestLine - latestLine));
    27 
    28                         WebUtils.WriteJson (_context.Response, result);
     56                        SendEnvelopedResult (_context, ref writer);
    2957                }
    3058
  • binary-improvements2/WebServer/src/WebAPI/AbsRestApi.cs

    r394 r402  
    11using System;
     2using System.Collections.Generic;
    23using System.IO;
    34using System.Net;
    4 using AllocsFixes.JSON;
     5using Utf8Json;
    56
    67namespace Webserver.WebAPI {
     
    910
    1011                public sealed override void HandleRequest (RequestContext _context) {
    11                         JsonNode jsonBody = null;
     12                        IDictionary<string, object> inputJson = null;
     13                        byte[] jsonInputData = null;
     14                       
     15                        if (_context.Request.HasEntityBody) {
     16                                Stream requestInputStream = _context.Request.InputStream;
     17                               
     18                                jsonInputData = new byte[_context.Request.ContentLength64];
     19                                requestInputStream.Read (jsonInputData, 0, (int)_context.Request.ContentLength64);
     20                               
     21                                try {
     22                                        jsonDeserializeSampler.Begin ();
     23                                        inputJson = JsonSerializer.Deserialize<IDictionary<string, object>> (jsonInputData);
     24                                       
     25                                        // Log.Out ("JSON body:");
     26                                        // foreach ((string key, object value) in inputJson) {
     27                                        //      Log.Out ($" - {key} = {value} ({value.GetType ()})");
     28                                        // }
     29                                       
     30                                        jsonDeserializeSampler.End ();
     31                                } catch (Exception e) {
     32                                        jsonDeserializeSampler.End ();
    1233
    13                         if (_context.Request.HasEntityBody) {
    14                                 string body = new StreamReader (_context.Request.InputStream).ReadToEnd ();
    15 
    16                                 if (!string.IsNullOrEmpty (body)) {
    17                                         try {
    18                                                 jsonDeserializeSampler.Begin ();
    19                                                 jsonBody = Parser.Parse (body);
    20                                                 jsonDeserializeSampler.End ();
    21                                         } catch (Exception e) {
    22                                                 jsonDeserializeSampler.End ();
    23 
    24                                                 SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, null, "INVALID_BODY", e);
    25                                                 return;
    26                                         }
     34                                        SendErrorResult (_context, HttpStatusCode.BadRequest, null, "INVALID_BODY", e);
     35                                        return;
    2736                                }
    2837                        }
     
    3140                                switch (_context.Request.HttpMethod) {
    3241                                        case "GET":
    33                                                 if (jsonBody != null) {
    34                                                         SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, jsonBody, "GET_WITH_BODY");
     42                                                if (inputJson != null) {
     43                                                        SendErrorResult (_context, HttpStatusCode.BadRequest, jsonInputData, "GET_WITH_BODY");
    3544                                                        return;
    3645                                                }
     
    4049                                        case "POST":
    4150                                                if (!string.IsNullOrEmpty (_context.RequestPath)) {
    42                                                         SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, jsonBody, "POST_WITH_ID");
     51                                                        SendErrorResult (_context, HttpStatusCode.BadRequest, jsonInputData, "POST_WITH_ID");
    4352                                                        return;
    4453                                                }
    4554
    46                                                 if (jsonBody == null) {
    47                                                         SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, null, "POST_WITHOUT_BODY");
     55                                                if (inputJson == null) {
     56                                                        SendErrorResult (_context, HttpStatusCode.BadRequest, null, "POST_WITHOUT_BODY");
    4857                                                        return;
    4958                                                }
    5059
    51                                                 HandleRestPost (_context, jsonBody);
     60                                                HandleRestPost (_context, inputJson, jsonInputData);
    5261                                                return;
    5362                                        case "PUT":
    5463                                                if (string.IsNullOrEmpty (_context.RequestPath)) {
    55                                                         SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, jsonBody, "PUT_WITHOUT_ID");
     64                                                        SendErrorResult (_context, HttpStatusCode.BadRequest, jsonInputData, "PUT_WITHOUT_ID");
    5665                                                        return;
    5766                                                }
    5867
    59                                                 if (jsonBody == null) {
    60                                                         SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, null, "PUT_WITHOUT_BODY");
     68                                                if (inputJson == null) {
     69                                                        SendErrorResult (_context, HttpStatusCode.BadRequest, null, "PUT_WITHOUT_BODY");
    6170                                                        return;
    6271                                                }
    6372
    64                                                 HandleRestPut (_context, jsonBody);
     73                                                HandleRestPut (_context, inputJson, jsonInputData);
    6574                                                return;
    6675                                        case "DELETE":
    6776                                                if (string.IsNullOrEmpty (_context.RequestPath)) {
    68                                                         SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, jsonBody, "DELETE_WITHOUT_ID");
     77                                                        SendErrorResult (_context, HttpStatusCode.BadRequest, jsonInputData, "DELETE_WITHOUT_ID");
    6978                                                        return;
    7079                                                }
    7180
    72                                                 if (jsonBody != null) {
    73                                                         SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, null, "DELETE_WITH_BODY");
     81                                                if (inputJson != null) {
     82                                                        SendErrorResult (_context, HttpStatusCode.BadRequest, null, "DELETE_WITH_BODY");
    7483                                                        return;
    7584                                                }
     
    7887                                                return;
    7988                                        default:
    80                                                 SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, null, "INVALID_METHOD");
     89                                                SendErrorResult (_context, HttpStatusCode.BadRequest, null, "INVALID_METHOD");
    8190                                                return;
    8291                                }
    8392                        } catch (Exception e) {
    84                                 SendEnvelopedResult (_context, null, HttpStatusCode.InternalServerError, jsonBody, "ERROR_PROCESSING", e);
     93                                SendErrorResult (_context, HttpStatusCode.InternalServerError, jsonInputData, "ERROR_PROCESSING", e);
    8594                        }
    8695                }
    8796
    88                 private static readonly JsonArray emptyData = new JsonArray ();
    89 
    90                 protected void SendEnvelopedResult (RequestContext _context, JsonNode _resultData, HttpStatusCode _statusCode = HttpStatusCode.OK,
    91                         JsonNode _jsonInputBody = null, string _errorCode = null, Exception _exception = null) {
    92                         JsonObject meta = new JsonObject ();
    93 
    94                         meta.Add ("serverTime", new JsonString (DateTime.Now.ToString ("o")));
    95                         if (!string.IsNullOrEmpty (_errorCode)) {
    96                                 meta.Add ("requestMethod", new JsonString (_context.Request.HttpMethod));
    97                                 meta.Add ("requestSubpath", new JsonString (_context.RequestPath));
    98                                 meta.Add ("requestBody", new JsonString (_jsonInputBody?.ToString () ?? "-empty-"));
    99                                 meta.Add ("errorCode", new JsonString (_errorCode));
    100                                 if (_exception != null) {
    101                                         meta.Add ("exceptionMessage", new JsonString (_exception.Message));
    102                                         meta.Add ("exceptionTrace", new JsonString (_exception.StackTrace));
    103                                 }
    104                         }
    105 
    106                         JsonObject envelope = new JsonObject ();
    107                         envelope.Add ("meta", meta);
    108                         envelope.Add ("data", _resultData ?? emptyData);
    109 
    110                         WebUtils.WriteJson (_context.Response, envelope, _statusCode);
     97                protected void SendErrorResult (RequestContext _context, HttpStatusCode _statusCode, byte[] _jsonInputData = null, string _errorCode = null, Exception _exception = null) {
     98                        PrepareEnvelopedResult (out JsonWriter writer);
     99                        writer.WriteRaw (JsonEmptyData);
     100                        SendEnvelopedResult (_context, ref writer, _statusCode, _jsonInputData, _errorCode, _exception);
    111101                }
    112102
    113                 protected bool TryGetJsonField (JsonObject _jsonObject, string _fieldName, out int _value) {
     103                static AbsRestApi () {
     104                        JsonWriter writer = new JsonWriter ();
     105                        writer.WriteBeginArray ();
     106                        writer.WriteEndArray ();
     107                        JsonEmptyData = writer.ToUtf8ByteArray ();
     108                }
     109
     110                protected static readonly byte[] JsonEmptyData;
     111               
     112                protected void PrepareEnvelopedResult (out JsonWriter _writer) {
     113                        WebUtils.PrepareEnvelopedResult (out _writer);
     114                }
     115
     116                protected void SendEnvelopedResult (RequestContext _context, ref JsonWriter _writer, HttpStatusCode _statusCode = HttpStatusCode.OK,
     117                        byte[] _jsonInputData = null, string _errorCode = null, Exception _exception = null) {
     118                       
     119                        WebUtils.SendEnvelopedResult (_context, ref _writer, _statusCode, _jsonInputData, _errorCode, _exception);
     120                }
     121
     122                protected bool TryGetJsonField (IDictionary<string, object> _jsonObject, string _fieldName, out int _value) {
    114123                        _value = default;
    115124                       
    116                         if (!_jsonObject.TryGetValue (_fieldName, out JsonNode fieldNode)) {
     125                        if (!_jsonObject.TryGetValue (_fieldName, out object fieldNode)) {
    117126                                return false;
    118127                        }
    119128
    120                         if (!(fieldNode is JsonValue valueField)) {
     129                        if (fieldNode is not double value) {
    121130                                return false;
    122131                        }
    123132
    124133                        try {
    125                                 _value = valueField.AsInt;
     134                                _value = (int)value;
    126135                                return true;
    127136                        } catch (Exception) {
     
    130139                }
    131140
    132                 protected bool TryGetJsonField (JsonObject _jsonObject, string _fieldName, out double _value) {
     141                protected bool TryGetJsonField (IDictionary<string, object> _jsonObject, string _fieldName, out double _value) {
    133142                        _value = default;
    134143                       
    135                         if (!_jsonObject.TryGetValue (_fieldName, out JsonNode fieldNode)) {
     144                        if (!_jsonObject.TryGetValue (_fieldName, out object fieldNode)) {
    136145                                return false;
    137146                        }
    138147
    139                         if (!(fieldNode is JsonValue valueField)) {
     148                        if (fieldNode is not double value) {
    140149                                return false;
    141150                        }
    142151
    143152                        try {
    144                                 _value = valueField.AsDouble;
     153                                _value = value;
    145154                                return true;
    146155                        } catch (Exception) {
     
    149158                }
    150159
    151                 protected bool TryGetJsonField (JsonObject _jsonObject, string _fieldName, out string _value) {
     160                protected bool TryGetJsonField (IDictionary<string, object> _jsonObject, string _fieldName, out string _value) {
    152161                        _value = default;
    153162                       
    154                         if (!_jsonObject.TryGetValue (_fieldName, out JsonNode fieldNode)) {
     163                        if (!_jsonObject.TryGetValue (_fieldName, out object fieldNode)) {
    155164                                return false;
    156165                        }
    157166
    158                         if (!(fieldNode is JsonValue valueField)) {
     167                        if (fieldNode is not string value) {
    159168                                return false;
    160169                        }
    161170
    162171                        try {
    163                                 _value = valueField.AsString;
     172                                _value = value;
    164173                                return true;
    165174                        } catch (Exception) {
     
    168177                }
    169178
    170                 protected abstract void HandleRestGet (RequestContext _context);
     179                protected virtual void HandleRestGet (RequestContext _context) {
     180                        SendErrorResult (_context, HttpStatusCode.MethodNotAllowed, null, "Unsupported");
     181                }
    171182
    172                 protected abstract void HandleRestPost (RequestContext _context, JsonNode _jsonBody);
     183                protected virtual void HandleRestPost (RequestContext _context, IDictionary<string, object> _jsonInput, byte[] _jsonInputData) {
     184                        SendErrorResult (_context, HttpStatusCode.MethodNotAllowed, _jsonInputData, "Unsupported");
     185                }
    173186
    174                 protected abstract void HandleRestPut (RequestContext _context, JsonNode _jsonBody);
     187                protected virtual void HandleRestPut (RequestContext _context, IDictionary<string, object> _jsonInput, byte[] _jsonInputData) {
     188                        SendErrorResult (_context, HttpStatusCode.MethodNotAllowed, _jsonInputData, "Unsupported");
     189                }
    175190
    176                 protected abstract void HandleRestDelete (RequestContext _context);
     191                protected virtual void HandleRestDelete (RequestContext _context) {
     192                        SendErrorResult (_context, HttpStatusCode.MethodNotAllowed, null, "Unsupported");
     193                }
    177194        }
    178195}
Note: See TracChangeset for help on using the changeset viewer.