Changeset 434


Ignore:
Timestamp:
May 17, 2023, 11:05:59 PM (19 months ago)
Author:
alloc
Message:

Added permission management APIs

Location:
binary-improvements2
Files:
8 added
39 edited

Legend:

Unmodified
Added
Removed
  • binary-improvements2/CommandExtensions/ModInfo.xml

    r432 r434  
    55        <Description value="Additional commands for server operation" />
    66        <Author value="The Fun Pimps LLC" />
    7         <Version value="21.0.280.0" />
     7        <Version value="21.0.288.0" />
    88        <Website value="" />
    99</xml>
  • binary-improvements2/MapRendering/ModInfo.xml

    r432 r434  
    55        <Description value="Render the game map to image map tiles as it is uncovered" />
    66        <Author value="The Fun Pimps LLC" />
    7         <Version value="21.0.280.0" />
     7        <Version value="21.0.288.0" />
    88        <Website value="" />
    99</xml>
  • binary-improvements2/MapRendering/src/Api/Map.cs

    r426 r434  
    2424                                        break;
    2525                                default:
    26                                         SendErrorResult (_context, HttpStatusCode.NotImplemented, _errorCode: "INVALID_ID");
     26                                        SendEmptyResponse (_context, HttpStatusCode.NotImplemented, _errorCode: "INVALID_ID");
    2727                                        return;
    2828                        }
  • binary-improvements2/MarkersMod/ModInfo.xml

    r432 r434  
    55        <Description value="Allows placing custom markers on the web map" />
    66        <Author value="Catalysm and Alloc" />
    7         <Version value="21.0.280.0" />
     7        <Version value="21.0.288.0" />
    88        <Website value="" />
    99</xml>
  • binary-improvements2/MarkersMod/src/Markers.cs

    r430 r434  
    2626                                markers.Add (WebUtils.GenerateGuid (), (lat, lng, null));
    2727                        }
     28                       
     29                        GameRandomManager.Instance.FreeGameRandom (random);
    2830                }
    2931
     
    5860
    5961                        if (!markers.TryGetValue (id, out (int, int, string) properties2)) {
    60                                 writer.WriteRaw (JsonEmptyData);
     62                                writer.WriteRaw (WebUtils.JsonEmptyData);
    6163                                SendEnvelopedResult (_context, ref writer, HttpStatusCode.NotFound);
    6264                                return;
     
    7779                        _writer.WriteString (_markerId);
    7880                        _writer.WriteRaw (jsonKeyLat);
    79                         _writer.WriteInt32 (_properties.Item1);
     81                        (int lat, int lng, string icon) = _properties;
     82                        _writer.WriteInt32 (lat);
    8083                        _writer.WriteRaw (jsonKeyLng);
    81                         _writer.WriteInt32 (_properties.Item2);
     84                        _writer.WriteInt32 (lng);
    8285                        _writer.WriteRaw (jsonKeyIcon);
    83                         _writer.WriteString (_properties.Item3 ?? defaultIcon);
     86                        _writer.WriteString (icon ?? defaultIcon);
    8487                        _writer.WriteEndObject ();
    8588                }
    8689
    8790                protected override void HandleRestPost (RequestContext _context, IDictionary<string, object> _jsonInput, byte[] _jsonInputData) {
    88                         if (!TryGetJsonField (_jsonInput, "lat", out int lat)) {
    89                                 SendErrorResult (_context, HttpStatusCode.BadRequest, _jsonInputData, "NO_OR_INVALID_LAT");
     91                        if (!JsonCommons.TryGetJsonField (_jsonInput, "lat", out int lat)) {
     92                                SendEmptyResponse (_context, HttpStatusCode.BadRequest, _jsonInputData, "NO_OR_INVALID_LAT");
    9093                                return;
    9194                        }
    9295
    93                         if (!TryGetJsonField (_jsonInput, "lng", out int lng)) {
    94                                 SendErrorResult (_context, HttpStatusCode.BadRequest, _jsonInputData, "NO_OR_INVALID_LNG");
     96                        if (!JsonCommons.TryGetJsonField (_jsonInput, "lng", out int lng)) {
     97                                SendEmptyResponse (_context, HttpStatusCode.BadRequest, _jsonInputData, "NO_OR_INVALID_LNG");
    9598                                return;
    9699                        }
    97100
    98                         TryGetJsonField (_jsonInput, "icon", out string icon);
     101                        JsonCommons.TryGetJsonField (_jsonInput, "icon", out string icon);
    99102                        if (string.IsNullOrEmpty (icon)) {
    100103                                icon = null;
     
    110113
    111114                protected override void HandleRestPut (RequestContext _context, IDictionary<string, object> _jsonInput, byte[] _jsonInputData) {
    112                         if (!TryGetJsonField (_jsonInput, "lat", out int lat)) {
    113                                 SendErrorResult (_context, HttpStatusCode.BadRequest, _jsonInputData, "NO_OR_INVALID_LAT");
     115                        if (!JsonCommons.TryGetJsonField (_jsonInput, "lat", out int lat)) {
     116                                SendEmptyResponse (_context, HttpStatusCode.BadRequest, _jsonInputData, "NO_OR_INVALID_LAT");
    114117                                return;
    115118                        }
    116119
    117                         if (!TryGetJsonField (_jsonInput, "lng", out int lng)) {
    118                                 SendErrorResult (_context, HttpStatusCode.BadRequest, _jsonInputData, "NO_OR_INVALID_LNG");
     120                        if (!JsonCommons.TryGetJsonField (_jsonInput, "lng", out int lng)) {
     121                                SendEmptyResponse (_context, HttpStatusCode.BadRequest, _jsonInputData, "NO_OR_INVALID_LNG");
    119122                                return;
    120123                        }
    121124
    122125                        bool keepIcon = !_jsonInput.TryGetValue ("icon", out _);
    123                         TryGetJsonField (_jsonInput, "icon", out string icon);
     126                        JsonCommons.TryGetJsonField (_jsonInput, "icon", out string icon);
    124127                        if (string.IsNullOrEmpty (icon)) {
    125128                                icon = null;
     
    129132
    130133                        if (!markers.TryGetValue (id, out (int, int, string) properties)) {
    131                                 SendErrorResult (_context, HttpStatusCode.NotFound, _jsonInputData, "ID_NOT_FOUND");
     134                                SendEmptyResponse (_context, HttpStatusCode.NotFound, _jsonInputData, "ID_NOT_FOUND");
    132135                                return;
    133136                        }
     
    154157                        string id = _context.RequestPath;
    155158
    156                         PrepareEnvelopedResult (out JsonWriter writer);
    157                         writer.WriteRaw (JsonEmptyData);
    158                         SendEnvelopedResult (_context, ref writer, markers.Remove (id) ? HttpStatusCode.NoContent : HttpStatusCode.NotFound);
     159                        SendEmptyResponse (_context, markers.Remove (id) ? HttpStatusCode.NoContent : HttpStatusCode.NotFound);
    159160                }
    160161               
  • binary-improvements2/WebServer/ModInfo.xml

    r432 r434  
    55        <Description value="Integrated Webserver for the Web Dashboard and server APIs" />
    66        <Author value="The Fun Pimps LLC" />
    7         <Version value="21.0.280.0" />
     7        <Version value="21.0.288.0" />
    88        <Website value="" />
    99</xml>
  • binary-improvements2/WebServer/WebServer.csproj

    r433 r434  
    124124    <Compile Include="src\WebAPI\APIs\GameData\Mods.cs" />
    125125    <Compile Include="src\WebAPI\APIs\Log.cs" />
     126    <Compile Include="src\WebAPI\APIs\Permissions\Blacklist.cs" />
     127    <Compile Include="src\WebAPI\APIs\Permissions\CommandPermissions.cs" />
     128    <Compile Include="src\WebAPI\APIs\Permissions\PermissionsApiHelpers.cs" />
     129    <Compile Include="src\WebAPI\APIs\Permissions\UserPermissions.cs" />
    126130    <Compile Include="src\WebAPI\APIs\Permissions\RegisterUser.cs" />
     131    <Compile Include="src\WebAPI\APIs\Permissions\WebApiTokens.cs" />
     132    <Compile Include="src\WebAPI\APIs\Permissions\WebModules.cs" />
     133    <Compile Include="src\WebAPI\APIs\Permissions\WebUsers.cs" />
     134    <Compile Include="src\WebAPI\APIs\Permissions\Whitelist.cs" />
    127135    <Compile Include="src\WebAPI\APIs\ServerInfo.cs" />
    128136    <Compile Include="src\WebAPI\APIs\ServerStats.cs" />
  • binary-improvements2/WebServer/src/Commands/WebPermissionsCmd.cs

    r426 r434  
    139139
    140140                                SdtdConsole.Instance.Output ($"  {wmp.Name,-25}: {wmp.LevelGlobal,4}{(wmp.IsDefault ? " (default permissions)" : "")}");
    141                                 if (wmp.LevelPerMethod != null) {
    142                                         for (int iMethod = 0; iMethod < wmp.LevelPerMethod.Length; iMethod++) {
    143                                                 int methodLevel = wmp.LevelPerMethod [iMethod];
    144                                                 ERequestMethod method = (ERequestMethod)iMethod;
     141                                if (wmp.LevelPerMethod == null) {
     142                                        continue;
     143                                }
     144
     145                                for (int iMethod = 0; iMethod < wmp.LevelPerMethod.Length; iMethod++) {
     146                                        int methodLevel = wmp.LevelPerMethod [iMethod];
     147                                        ERequestMethod method = (ERequestMethod)iMethod;
    145148                                               
    146                                                 if (methodLevel == AdminWebModules.MethodLevelNotSupported) {
    147                                                         continue;
    148                                                 }
     149                                        if (methodLevel == AdminWebModules.MethodLevelNotSupported) {
     150                                                continue;
     151                                        }
    149152                                               
    150                                                 if (methodLevel == AdminWebModules.MethodLevelInheritGlobal) {
    151                                                         SdtdConsole.Instance.Output ($"  {method.ToStringCached (),25}: {wmp.LevelGlobal,4} (Using API level)");
    152                                                 } else {
    153                                                         SdtdConsole.Instance.Output ($"  {method.ToStringCached (),25}: {methodLevel,4}");
    154                                                 }
     153                                        if (methodLevel == AdminWebModules.MethodLevelInheritGlobal) {
     154                                                SdtdConsole.Instance.Output ($"  {method.ToStringCached (),25}: {wmp.LevelGlobal,4} (Using API level)");
     155                                        } else {
     156                                                SdtdConsole.Instance.Output ($"  {method.ToStringCached (),25}: {methodLevel,4}");
    155157                                        }
    156158                                }
  • binary-improvements2/WebServer/src/LogBuffer.cs

    r391 r434  
    6464                        lock (logEntries) {
    6565                                logEntries.Add (le);
    66                                 if (logEntries.Count > maxEntries) {
    67                                         listOffset += logEntries.Count - maxEntries;
    68                                         logEntries.RemoveRange (0, logEntries.Count - maxEntries);
     66                                if (logEntries.Count <= maxEntries) {
     67                                        return;
    6968                                }
     69
     70                                listOffset += logEntries.Count - maxEntries;
     71                                logEntries.RemoveRange (0, logEntries.Count - maxEntries);
    7072                        }
    7173                }
     
    124126
    125127                public class LogEntry {
    126                         public readonly DateTime timestamp;
    127                         public readonly string isoTime;
    128                         public readonly string message;
    129                         public readonly string trace;
    130                         public readonly LogType type;
    131                         public readonly long uptime;
     128                        public readonly DateTime Timestamp;
     129                        public readonly string IsoTime;
     130                        public readonly string Message;
     131                        public readonly string Trace;
     132                        public readonly LogType Type;
     133                        public readonly long Uptime;
    132134
    133135                        public LogEntry (DateTime _timestamp, string _message, string _trace, LogType _type, long _uptime) {
    134                                 timestamp = _timestamp;
    135                                 isoTime = _timestamp.ToString ("o");
     136                                Timestamp = _timestamp;
     137                                IsoTime = _timestamp.ToString ("o");
    136138
    137                                 message = _message;
    138                                 trace = _trace;
    139                                 type = _type;
    140                                 uptime = _uptime;
     139                                Message = _message;
     140                                Trace = _trace;
     141                                Type = _type;
     142                                Uptime = _uptime;
    141143                        }
    142144                }
  • binary-improvements2/WebServer/src/Permissions/AdminWebModules.cs

    r427 r434  
    11using System.Collections.Generic;
    22using System.Xml;
    3 using UnityEngine;
    43
    54namespace Webserver.Permissions {
  • binary-improvements2/WebServer/src/UrlHandlers/AbsHandler.cs

    r426 r434  
    33namespace Webserver.UrlHandlers {
    44        public abstract class AbsHandler {
    5                 protected readonly string moduleName;
     5                public readonly string ModuleName;
    66                protected string urlBasePath;
    77                protected Web parent;
    88
    9                 public string ModuleName => moduleName;
    109                public string UrlBasePath => urlBasePath;
    1110
    1211                protected AbsHandler (string _moduleName, int _defaultPermissionLevel = 0) {
    13                         moduleName = _moduleName;
     12                        ModuleName = _moduleName;
    1413                        AdminWebModules.Instance.AddKnownModule (new AdminWebModules.WebModule(_moduleName, _defaultPermissionLevel, true));
    1514                }
     
    1817
    1918                public virtual bool IsAuthorizedForHandler (WebConnection _user, int _permissionLevel) {
    20                         return moduleName == null || AdminWebModules.Instance.ModuleAllowedWithLevel (moduleName, _permissionLevel);
     19                        return ModuleName == null || AdminWebModules.Instance.ModuleAllowedWithLevel (ModuleName, _permissionLevel);
    2120                }
    2221
  • binary-improvements2/WebServer/src/Web.cs

    r431 r434  
    1919               
    2020                private readonly List<AbsHandler> handlers = new List<AbsHandler> ();
    21                 public readonly List<WebMod> webMods = new List<WebMod> ();
     21                public readonly List<WebMod> WebMods = new List<WebMod> ();
    2222                public readonly ConnectionHandler ConnectionHandler;
    2323
     
    134134                                        try {
    135135                                                WebMod webMod = new WebMod (this, mod, _useStaticCache);
    136                                                 webMods.Add (webMod);
     136                                                WebMods.Add (webMod);
    137137                                        } catch (InvalidDataException e) {
    138138                                                Log.Error ($"[Web] Could not load webmod from mod {mod.Name}: {e.Message}");
  • binary-improvements2/WebServer/src/WebAPI/APIs/Command.cs

    r426 r434  
    9191
    9292                protected override void HandleRestPost (RequestContext _context, IDictionary<string, object> _jsonInput, byte[] _jsonInputData) {
    93                         if (!TryGetJsonField (_jsonInput, "command", out string commandString)) {
    94                                 SendErrorResult (_context, HttpStatusCode.BadRequest, _jsonInputData, "NO_COMMAND");
     93                        if (!JsonCommons.TryGetJsonField (_jsonInput, "command", out string commandString)) {
     94                                SendEmptyResponse (_context, HttpStatusCode.BadRequest, _jsonInputData, "NO_COMMAND");
    9595                                return;
    9696                        }
     
    9898                        WebCommandResult.ResultType responseType = WebCommandResult.ResultType.Full;
    9999
    100                         if (TryGetJsonField (_jsonInput, "format", out string formatString)) {
     100                        if (JsonCommons.TryGetJsonField (_jsonInput, "format", out string formatString)) {
    101101                                if (formatString.EqualsCaseInsensitive ("raw")) {
    102102                                        responseType = WebCommandResult.ResultType.Raw;
     
    115115
    116116                        if (command == null) {
    117                                 SendErrorResult (_context, HttpStatusCode.NotFound, _jsonInputData, "UNKNOWN_COMMAND");
     117                                SendEmptyResponse (_context, HttpStatusCode.NotFound, _jsonInputData, "UNKNOWN_COMMAND");
    118118                                return;
    119119                        }
     
    122122
    123123                        if (_context.PermissionLevel > commandPermissionLevel) {
    124                                 SendErrorResult (_context, HttpStatusCode.Forbidden, _jsonInputData, "NO_PERMISSION");
     124                                SendEmptyResponse (_context, HttpStatusCode.Forbidden, _jsonInputData, "NO_PERMISSION");
    125125                                return;
    126126                        }
  • binary-improvements2/WebServer/src/WebAPI/APIs/GameData/Item.cs

    r433 r434  
    33using Webserver.Permissions;
    44
    5 namespace Webserver.WebAPI.APIs {
     5namespace Webserver.WebAPI.APIs.GameData {
    66        [UsedImplicitly]
    77        internal class Item : AbsRestApi {
  • binary-improvements2/WebServer/src/WebAPI/APIs/GameData/Mods.cs

    r433 r434  
    33using Webserver.Permissions;
    44
    5 namespace Webserver.WebAPI.APIs {
     5namespace Webserver.WebAPI.APIs.GameData {
    66        [UsedImplicitly]
    77        public class Mods : AbsRestApi {
     
    1212                        writer.WriteBeginArray ();
    1313
    14                         for (int i = 0; i < _parent.webMods.Count; i++) {
    15                                 WebMod webMod = _parent.webMods [i];
     14                        for (int i = 0; i < _parent.WebMods.Count; i++) {
     15                                WebMod webMod = _parent.WebMods [i];
    1616
    1717                                if (i > 0) {
     
    6262                        _writer.WriteValueSeparator ();
    6363                        _writer.WritePropertyName ("displayName");
    64                         JsonCommons.WriteStringOrNull (ref _writer, _webMod.ParentMod.DisplayName);
     64                        _writer.WriteString (_webMod.ParentMod.DisplayName);
    6565
    6666                        _writer.WriteValueSeparator ();
    6767                        _writer.WritePropertyName ("description");
    68                         JsonCommons.WriteStringOrNull (ref _writer, _webMod.ParentMod.Description);
     68                        _writer.WriteString (_webMod.ParentMod.Description);
    6969
    7070                        _writer.WriteValueSeparator ();
    7171                        _writer.WritePropertyName ("author");
    72                         JsonCommons.WriteStringOrNull (ref _writer, _webMod.ParentMod.Author);
     72                        _writer.WriteString (_webMod.ParentMod.Author);
    7373
    7474                        _writer.WriteValueSeparator ();
    7575                        _writer.WritePropertyName ("version");
    76                         JsonCommons.WriteStringOrNull (ref _writer, _webMod.ParentMod.VersionString);
     76                        _writer.WriteString (_webMod.ParentMod.VersionString);
    7777
    7878                        _writer.WriteValueSeparator ();
    7979                        _writer.WritePropertyName ("website");
    80                         JsonCommons.WriteStringOrNull (ref _writer, _webMod.ParentMod.Website);
     80                        _writer.WriteString (_webMod.ParentMod.Website);
    8181                }
    8282
  • binary-improvements2/WebServer/src/WebAPI/APIs/Log.cs

    r408 r434  
    5555
    5656                                writer.WriteRaw (jsonMsgKey);
    57                                 writer.WriteString (logEntry.message);
     57                                writer.WriteString (logEntry.Message);
    5858
    5959                                writer.WriteRaw (jsonTypeKey);
    60                                 writer.WriteString (logEntry.type.ToStringCached ());
     60                                writer.WriteString (logEntry.Type.ToStringCached ());
    6161
    6262                                writer.WriteRaw (jsonTraceKey);
    63                                 writer.WriteString (logEntry.trace);
     63                                writer.WriteString (logEntry.Trace);
    6464
    6565                                writer.WriteRaw (jsonIsotimeKey);
    66                                 writer.WriteString (logEntry.isoTime);
     66                                writer.WriteString (logEntry.IsoTime);
    6767
    6868                                writer.WriteRaw (jsonUptimeKey);
    69                                 writer.WriteString (logEntry.uptime.ToString ());
     69                                writer.WriteString (logEntry.Uptime.ToString ());
    7070
    7171                                writer.WriteEndObject ();
  • binary-improvements2/WebServer/src/WebAPI/APIs/Permissions/RegisterUser.cs

    r433 r434  
    99using Webserver.UrlHandlers;
    1010
    11 namespace Webserver.WebAPI.APIs {
     11namespace Webserver.WebAPI.APIs.Permissions {
    1212        [UsedImplicitly]
    1313        public class RegisterUser : AbsRestApi {
     
    2727
    2828                        if (string.IsNullOrEmpty (token)) {
    29                                 SendErrorResult (_context, HttpStatusCode.BadRequest, null, "NO_TOKEN");
     29                                SendEmptyResponse (_context, HttpStatusCode.BadRequest, null, "NO_TOKEN");
    3030                                return;
    3131                        }
    3232
    3333                        if (!UserRegistrationTokens.TryValidate (token, out UserRegistrationTokens.RegistrationData regData)) {
    34                                 SendErrorResult (_context, HttpStatusCode.NotFound, null, "INVALID_OR_EXPIRED_TOKEN");
     34                                SendEmptyResponse (_context, HttpStatusCode.NotFound, null, "INVALID_OR_EXPIRED_TOKEN");
    3535                                return;
    3636                        }
     
    5050
    5151                protected override void HandleRestPost (RequestContext _context, IDictionary<string, object> _jsonInput, byte[] _jsonInputData) {
    52                         if (!TryGetJsonField (_jsonInput, "token", out string token)) {
    53                                 SendErrorResult (_context, HttpStatusCode.BadRequest, _jsonInputData, "MISSING_TOKEN");
     52                        if (!JsonCommons.TryGetJsonField (_jsonInput, "token", out string token)) {
     53                                SendEmptyResponse (_context, HttpStatusCode.BadRequest, _jsonInputData, "MISSING_TOKEN");
    5454                                return;
    5555                        }
    5656
    57                         if (!TryGetJsonField (_jsonInput, "username", out string username)) {
    58                                 SendErrorResult (_context, HttpStatusCode.BadRequest, _jsonInputData, "MISSING_USERNAME");
     57                        if (!JsonCommons.TryGetJsonField (_jsonInput, "username", out string username)) {
     58                                SendEmptyResponse (_context, HttpStatusCode.BadRequest, _jsonInputData, "MISSING_USERNAME");
    5959                                return;
    6060                        }
    6161
    62                         if (!TryGetJsonField (_jsonInput, "password", out string password)) {
    63                                 SendErrorResult (_context, HttpStatusCode.BadRequest, _jsonInputData, "MISSING_PASSWORD");
     62                        if (!JsonCommons.TryGetJsonField (_jsonInput, "password", out string password)) {
     63                                SendEmptyResponse (_context, HttpStatusCode.BadRequest, _jsonInputData, "MISSING_PASSWORD");
    6464                                return;
    6565                        }
    6666
    6767                        if (!UserRegistrationTokens.TryValidate (token, out UserRegistrationTokens.RegistrationData regData)) {
    68                                 SendErrorResult (_context, HttpStatusCode.Unauthorized, null, "INVALID_OR_EXPIRED_TOKEN");
     68                                SendEmptyResponse (_context, HttpStatusCode.Unauthorized, null, "INVALID_OR_EXPIRED_TOKEN");
    6969                                return;
    7070                        }
    7171
    7272                        if (!userValidationRegex.IsMatch (username)) {
    73                                 SendErrorResult (_context, HttpStatusCode.Unauthorized, _jsonInputData, "INVALID_USERNAME");
     73                                SendEmptyResponse (_context, HttpStatusCode.Unauthorized, _jsonInputData, "INVALID_USERNAME");
    7474                                return;
    7575                        }
    7676                       
    7777                        if (!passValidationRegex.IsMatch (password)) {
    78                                 SendErrorResult (_context, HttpStatusCode.Unauthorized, _jsonInputData, "INVALID_PASSWORD");
     78                                SendEmptyResponse (_context, HttpStatusCode.Unauthorized, _jsonInputData, "INVALID_PASSWORD");
    7979                                return;
    8080                        }
     
    8686                                    !PlatformUserIdentifierAbs.Equals (existingMapping.CrossPlatformUser, regData.CrossPlatformUserId)) {
    8787                                        // Username already in use by another player
    88                                         SendErrorResult (_context, HttpStatusCode.Unauthorized, _jsonInputData, "DUPLICATE_USERNAME");
     88                                        SendEmptyResponse (_context, HttpStatusCode.Unauthorized, _jsonInputData, "DUPLICATE_USERNAME");
    8989                                        return;
    9090                                }
  • binary-improvements2/WebServer/src/WebAPI/APIs/WorldState/Animal.cs

    r433 r434  
    44using Webserver.LiveData;
    55
    6 namespace Webserver.WebAPI.APIs {
     6namespace Webserver.WebAPI.APIs.WorldState {
    77        [UsedImplicitly]
    88        internal class Animal : AbsRestApi {
  • binary-improvements2/WebServer/src/WebAPI/APIs/WorldState/Hostile.cs

    r433 r434  
    44using Webserver.LiveData;
    55
    6 namespace Webserver.WebAPI.APIs {
     6namespace Webserver.WebAPI.APIs.WorldState {
    77        [UsedImplicitly]
    88        internal class Hostile : AbsRestApi {
  • binary-improvements2/WebServer/src/WebAPI/APIs/WorldState/Player.cs

    r433 r434  
    66using Webserver.Permissions;
    77
    8 namespace Webserver.WebAPI.APIs {
     8namespace Webserver.WebAPI.APIs.WorldState {
    99        [UsedImplicitly]
    1010        public class Player : AbsRestApi {
     
    216216
    217217                protected override void HandleRestPost (RequestContext _context, IDictionary<string, object> _jsonInput, byte[] _jsonInputData) {
    218                         if (!TryGetJsonField (_jsonInput, "command", out string commandString)) {
    219                                 SendErrorResult (_context, HttpStatusCode.BadRequest, _jsonInputData, "NO_COMMAND");
     218                        if (!JsonCommons.TryGetJsonField (_jsonInput, "command", out string commandString)) {
     219                                SendEmptyResponse (_context, HttpStatusCode.BadRequest, _jsonInputData, "NO_COMMAND");
    220220                                return;
    221221                        }
     
    223223                        WebCommandResult.ResultType responseType = WebCommandResult.ResultType.Full;
    224224
    225                         if (TryGetJsonField (_jsonInput, "format", out string formatString)) {
     225                        if (JsonCommons.TryGetJsonField (_jsonInput, "format", out string formatString)) {
    226226                                if (formatString.EqualsCaseInsensitive ("raw")) {
    227227                                        responseType = WebCommandResult.ResultType.Raw;
     
    240240
    241241                        if (command == null) {
    242                                 SendErrorResult (_context, HttpStatusCode.NotFound, _jsonInputData, "UNKNOWN_COMMAND");
     242                                SendEmptyResponse (_context, HttpStatusCode.NotFound, _jsonInputData, "UNKNOWN_COMMAND");
    243243                                return;
    244244                        }
     
    247247
    248248                        if (_context.PermissionLevel > commandPermissionLevel) {
    249                                 SendErrorResult (_context, HttpStatusCode.Forbidden, _jsonInputData, "NO_PERMISSION");
     249                                SendEmptyResponse (_context, HttpStatusCode.Forbidden, _jsonInputData, "NO_PERMISSION");
    250250                                return;
    251251                        }
  • binary-improvements2/WebServer/src/WebAPI/AbsRestApi.cs

    r426 r434  
    4444                                        jsonDeserializeSampler.End ();
    4545
    46                                         SendErrorResult (_context, HttpStatusCode.BadRequest, null, "INVALID_BODY", e);
     46                                        SendEmptyResponse (_context, HttpStatusCode.BadRequest, null, "INVALID_BODY", e);
    4747                                        return;
    4848                                }
     
    5353                                        case ERequestMethod.GET:
    5454                                                if (inputJson != null) {
    55                                                         SendErrorResult (_context, HttpStatusCode.BadRequest, jsonInputData, "GET_WITH_BODY");
     55                                                        SendEmptyResponse (_context, HttpStatusCode.BadRequest, jsonInputData, "GET_WITH_BODY");
    5656                                                        return;
    5757                                                }
     
    6060                                                return;
    6161                                        case ERequestMethod.POST:
    62                                                 if (!string.IsNullOrEmpty (_context.RequestPath)) {
    63                                                         SendErrorResult (_context, HttpStatusCode.BadRequest, jsonInputData, "POST_WITH_ID");
     62                                                if (!AllowPostWithId && !string.IsNullOrEmpty (_context.RequestPath)) {
     63                                                        SendEmptyResponse (_context, HttpStatusCode.BadRequest, jsonInputData, "POST_WITH_ID");
    6464                                                        return;
    6565                                                }
    6666
    6767                                                if (inputJson == null) {
    68                                                         SendErrorResult (_context, HttpStatusCode.BadRequest, null, "POST_WITHOUT_BODY");
     68                                                        SendEmptyResponse (_context, HttpStatusCode.BadRequest, null, "POST_WITHOUT_BODY");
    6969                                                        return;
    7070                                                }
     
    7474                                        case ERequestMethod.PUT:
    7575                                                if (string.IsNullOrEmpty (_context.RequestPath)) {
    76                                                         SendErrorResult (_context, HttpStatusCode.BadRequest, jsonInputData, "PUT_WITHOUT_ID");
     76                                                        SendEmptyResponse (_context, HttpStatusCode.BadRequest, jsonInputData, "PUT_WITHOUT_ID");
    7777                                                        return;
    7878                                                }
    7979
    8080                                                if (inputJson == null) {
    81                                                         SendErrorResult (_context, HttpStatusCode.BadRequest, null, "PUT_WITHOUT_BODY");
     81                                                        SendEmptyResponse (_context, HttpStatusCode.BadRequest, null, "PUT_WITHOUT_BODY");
    8282                                                        return;
    8383                                                }
     
    8787                                        case ERequestMethod.DELETE:
    8888                                                if (string.IsNullOrEmpty (_context.RequestPath)) {
    89                                                         SendErrorResult (_context, HttpStatusCode.BadRequest, jsonInputData, "DELETE_WITHOUT_ID");
     89                                                        SendEmptyResponse (_context, HttpStatusCode.BadRequest, jsonInputData, "DELETE_WITHOUT_ID");
    9090                                                        return;
    9191                                                }
    9292
    9393                                                if (inputJson != null) {
    94                                                         SendErrorResult (_context, HttpStatusCode.BadRequest, null, "DELETE_WITH_BODY");
     94                                                        SendEmptyResponse (_context, HttpStatusCode.BadRequest, null, "DELETE_WITH_BODY");
    9595                                                        return;
    9696                                                }
     
    9999                                                return;
    100100                                        default:
    101                                                 SendErrorResult (_context, HttpStatusCode.BadRequest, null, "INVALID_METHOD");
     101                                                SendEmptyResponse (_context, HttpStatusCode.BadRequest, null, "INVALID_METHOD");
    102102                                                return;
    103103                                }
    104104                        } catch (Exception e) {
    105                                 SendErrorResult (_context, HttpStatusCode.InternalServerError, jsonInputData, "ERROR_PROCESSING", e);
     105                                SendEmptyResponse (_context, HttpStatusCode.InternalServerError, jsonInputData, "ERROR_PROCESSING", e);
    106106                        }
    107107                }
    108108
    109109                protected virtual void HandleRestGet (RequestContext _context) {
    110                         SendErrorResult (_context, HttpStatusCode.MethodNotAllowed, null, "Unsupported");
     110                        SendEmptyResponse (_context, HttpStatusCode.MethodNotAllowed, null, "Unsupported");
    111111                }
    112112
    113113                protected virtual void HandleRestPost (RequestContext _context, IDictionary<string, object> _jsonInput, byte[] _jsonInputData) {
    114                         SendErrorResult (_context, HttpStatusCode.MethodNotAllowed, _jsonInputData, "Unsupported");
     114                        SendEmptyResponse (_context, HttpStatusCode.MethodNotAllowed, _jsonInputData, "Unsupported");
    115115                }
    116116
    117117                protected virtual void HandleRestPut (RequestContext _context, IDictionary<string, object> _jsonInput, byte[] _jsonInputData) {
    118                         SendErrorResult (_context, HttpStatusCode.MethodNotAllowed, _jsonInputData, "Unsupported");
     118                        SendEmptyResponse (_context, HttpStatusCode.MethodNotAllowed, _jsonInputData, "Unsupported");
    119119                }
    120120
    121121                protected virtual void HandleRestDelete (RequestContext _context) {
    122                         SendErrorResult (_context, HttpStatusCode.MethodNotAllowed, null, "Unsupported");
     122                        SendEmptyResponse (_context, HttpStatusCode.MethodNotAllowed, null, "Unsupported");
    123123                }
    124124
     
    126126                        AdminWebModules.WebModule module = AdminWebModules.Instance.GetModule (CachedApiModuleName);
    127127
    128                         if (module.LevelPerMethod != null) {
    129                                 int perMethodLevel = module.LevelPerMethod [(int)_context.Method];
    130                                 if (perMethodLevel == AdminWebModules.MethodLevelNotSupported) {
    131                                         return false;
    132                                 }
     128                        if (module.LevelPerMethod == null) {
     129                                return module.LevelGlobal >= _context.PermissionLevel;
     130                        }
    133131
    134                                 if (perMethodLevel != AdminWebModules.MethodLevelInheritGlobal) {
    135                                         return perMethodLevel >= _context.PermissionLevel;
    136                                 }
     132                        int perMethodLevel = module.LevelPerMethod [(int)_context.Method];
     133                        if (perMethodLevel == AdminWebModules.MethodLevelNotSupported) {
     134                                return false;
     135                        }
     136
     137                        if (perMethodLevel != AdminWebModules.MethodLevelInheritGlobal) {
     138                                return perMethodLevel >= _context.PermissionLevel;
    137139                        }
    138140
    139141                        return module.LevelGlobal >= _context.PermissionLevel;
    140142                }
     143
     144                protected virtual bool AllowPostWithId => false;
    141145
    142146                /// <summary>
     
    154158#region Helpers
    155159
    156                 protected static readonly byte[] JsonEmptyData;
    157                
    158                 static AbsRestApi () {
    159                         JsonWriter writer = new JsonWriter ();
    160                         writer.WriteBeginArray ();
    161                         writer.WriteEndArray ();
    162                         JsonEmptyData = writer.ToUtf8ByteArray ();
    163                 }
    164 
    165160                protected static void PrepareEnvelopedResult (out JsonWriter _writer) {
    166161                        WebUtils.PrepareEnvelopedResult (out _writer);
     
    173168                }
    174169
    175                 protected static void SendErrorResult (RequestContext _context, HttpStatusCode _statusCode, byte[] _jsonInputData = null, string _errorCode = null, Exception _exception = null) {
     170                protected static void SendEmptyResponse (RequestContext _context, HttpStatusCode _statusCode = HttpStatusCode.OK, byte[] _jsonInputData = null, string _errorCode = null, Exception _exception = null) {
    176171                        PrepareEnvelopedResult (out JsonWriter writer);
    177                         writer.WriteRaw (JsonEmptyData);
     172                        writer.WriteRaw (WebUtils.JsonEmptyData);
    178173                        SendEnvelopedResult (_context, ref writer, _statusCode, _jsonInputData, _errorCode, _exception);
    179174                }
    180 
    181                 protected static bool TryGetJsonField (IDictionary<string, object> _jsonObject, string _fieldName, out int _value) {
    182                         _value = default;
    183                        
    184                         if (!_jsonObject.TryGetValue (_fieldName, out object fieldNode)) {
    185                                 return false;
    186                         }
    187 
    188                         if (fieldNode is not double value) {
    189                                 return false;
    190                         }
    191 
    192                         try {
    193                                 _value = (int)value;
    194                                 return true;
    195                         } catch (Exception) {
    196                                 return false;
    197                         }
    198                 }
    199 
    200                 protected static bool TryGetJsonField (IDictionary<string, object> _jsonObject, string _fieldName, out double _value) {
    201                         _value = default;
    202                        
    203                         if (!_jsonObject.TryGetValue (_fieldName, out object fieldNode)) {
    204                                 return false;
    205                         }
    206 
    207                         if (fieldNode is not double value) {
    208                                 return false;
    209                         }
    210 
    211                         try {
    212                                 _value = value;
    213                                 return true;
    214                         } catch (Exception) {
    215                                 return false;
    216                         }
    217                 }
    218 
    219                 protected static bool TryGetJsonField (IDictionary<string, object> _jsonObject, string _fieldName, out string _value) {
    220                         _value = default;
    221                        
    222                         if (!_jsonObject.TryGetValue (_fieldName, out object fieldNode)) {
    223                                 return false;
    224                         }
    225 
    226                         if (fieldNode is not string value) {
    227                                 return false;
    228                         }
    229 
    230                         try {
    231                                 _value = value;
    232                                 return true;
    233                         } catch (Exception) {
    234                                 return false;
    235                         }
    236                 }
    237                
    238175
    239176#endregion
  • binary-improvements2/WebServer/src/WebAPI/JsonCommons.cs

    r426 r434  
    11using System;
     2using System.Collections.Generic;
     3using System.Globalization;
    24using UnityEngine;
    35using Utf8Json;
     
    5759                }
    5860
     61                public static bool TryReadPlatformUserIdentifier (IDictionary<string, object> _jsonInput, out PlatformUserIdentifierAbs _userIdentifier) {
     62                        if (TryGetJsonField (_jsonInput, "combinedString", out string combinedString)) {
     63                                _userIdentifier = PlatformUserIdentifierAbs.FromCombinedString (combinedString, false);
     64                                if (_userIdentifier != null) {
     65                                        return true;
     66                                }
     67                        }
     68                       
     69                        if (!TryGetJsonField (_jsonInput, "platformId", out string platformId)) {
     70                                _userIdentifier = default;
     71                                return false;
     72                        }
     73
     74                        if (!TryGetJsonField (_jsonInput, "userId", out string userId)) {
     75                                _userIdentifier = default;
     76                                return false;
     77                        }
     78
     79                        _userIdentifier = PlatformUserIdentifierAbs.FromPlatformAndId (platformId, userId, false);
     80                        return _userIdentifier != null;
     81                }
     82
    5983                public static void WriteDateTime (ref JsonWriter _writer, DateTime _dateTime) {
    6084                        _writer.WriteString (_dateTime.ToString ("o"));
    6185                }
    6286
    63                 public static void WriteStringOrNull (ref JsonWriter _writer, string _string) {
    64                         if (_string == null) {
    65                                 _writer.WriteNull ();
    66                         } else {
    67                                 _writer.WriteString (_string);
     87                public static bool TryReadDateTime (IDictionary<string, object> _jsonInput, string _fieldName, out DateTime _result) {
     88                        _result = default;
     89                       
     90                        if (!TryGetJsonField (_jsonInput, _fieldName, out string dateTimeString)) {
     91                                return false;
     92                        }
     93
     94                        return DateTime.TryParse (dateTimeString, null, DateTimeStyles.RoundtripKind, out _result);
     95                }
     96
     97
     98                public static bool TryGetJsonField (IDictionary<string, object> _jsonObject, string _fieldName, out int _value) {
     99                        _value = default;
     100                       
     101                        if (!_jsonObject.TryGetValue (_fieldName, out object fieldNode)) {
     102                                return false;
     103                        }
     104
     105                        if (fieldNode is not double value) {
     106                                return false;
     107                        }
     108
     109                        try {
     110                                _value = (int)value;
     111                                return true;
     112                        } catch (Exception) {
     113                                return false;
     114                        }
     115                }
     116
     117                public static bool TryGetJsonField (IDictionary<string, object> _jsonObject, string _fieldName, out double _value) {
     118                        _value = default;
     119                       
     120                        if (!_jsonObject.TryGetValue (_fieldName, out object fieldNode)) {
     121                                return false;
     122                        }
     123
     124                        if (fieldNode is not double value) {
     125                                return false;
     126                        }
     127
     128                        try {
     129                                _value = value;
     130                                return true;
     131                        } catch (Exception) {
     132                                return false;
     133                        }
     134                }
     135
     136                public static bool TryGetJsonField (IDictionary<string, object> _jsonObject, string _fieldName, out string _value) {
     137                        _value = default;
     138                       
     139                        if (!_jsonObject.TryGetValue (_fieldName, out object fieldNode)) {
     140                                return false;
     141                        }
     142
     143                        if (fieldNode is not string value) {
     144                                return false;
     145                        }
     146
     147                        try {
     148                                _value = value;
     149                                return true;
     150                        } catch (Exception) {
     151                                return false;
     152                        }
     153                }
     154
     155                public static bool TryGetJsonField (IDictionary<string, object> _jsonObject, string _fieldName,
     156                        out IDictionary<string, object> _value) {
     157                        _value = default;
     158                       
     159                        if (!_jsonObject.TryGetValue (_fieldName, out object fieldNode)) {
     160                                return false;
     161                        }
     162
     163                        if (fieldNode is not IDictionary<string, object> value) {
     164                                return false;
     165                        }
     166
     167                        try {
     168                                _value = value;
     169                                return true;
     170                        } catch (Exception) {
     171                                return false;
    68172                        }
    69173                }
  • binary-improvements2/WebServer/src/WebConnection.cs

    r425 r434  
    33using System.Net;
    44using UnityEngine;
    5 using Webserver.Permissions;
    65
    76namespace Webserver {
  • binary-improvements2/WebServer/src/WebMod.cs

    r426 r434  
    2020                        IsWebMod = Directory.Exists (folder);
    2121
    22                         if (IsWebMod) {
    23                                 string urlWebModBase = $"{modsBaseUrl}{_parentMod.FolderName}/";
     22                        if (!IsWebMod) {
     23                                return;
     24                        }
    2425
    25                                 ReactBundle = $"{folder}/{reactBundleName}";
    26                                 ReactBundle = File.Exists (ReactBundle) ? $"{urlWebModBase}{reactBundleName}" : null;
     26                        string urlWebModBase = $"{modsBaseUrl}{_parentMod.FolderName}/";
    2727
    28                                 CssPath = $"{folder}/{stylingFileName}";
    29                                 CssPath = File.Exists (CssPath) ? $"{urlWebModBase}{stylingFileName}" : null;
     28                        ReactBundle = $"{folder}/{reactBundleName}";
     29                        ReactBundle = File.Exists (ReactBundle) ? $"{urlWebModBase}{reactBundleName}" : null;
    3030
    31                                 _parentWeb.RegisterPathHandler (urlWebModBase, new StaticHandler (
    32                                         folder,
    33                                         _useStaticCache ? new SimpleCache () : new DirectAccess (),
    34                                         false)
    35                                 );
    36                         }
     31                        CssPath = $"{folder}/{stylingFileName}";
     32                        CssPath = File.Exists (CssPath) ? $"{urlWebModBase}{stylingFileName}" : null;
     33
     34                        _parentWeb.RegisterPathHandler (urlWebModBase, new StaticHandler (
     35                                folder,
     36                                _useStaticCache ? new SimpleCache () : new DirectAccess (),
     37                                false)
     38                        );
    3739                }
    3840        }
  • binary-improvements2/WebServer/src/WebUtils.cs

    r425 r434  
    44using System.Net;
    55using System.Text;
     6using UnityEngine.Profiling;
    67using Utf8Json;
    78using Webserver.WebAPI;
     
    1112namespace Webserver {
    1213        public static class WebUtils {
     14                static WebUtils () {
     15                        JsonWriter writer = new JsonWriter ();
     16                        writer.WriteBeginArray ();
     17                        writer.WriteEndArray ();
     18                        JsonEmptyData = writer.ToUtf8ByteArray ();
     19                }
     20
    1321                // ReSharper disable once MemberCanBePrivate.Global
    1422                public const string MimePlain = "text/plain";
     
    1725                public const string MimeJson = "application/json";
    1826               
    19                 private static readonly UnityEngine.Profiling.CustomSampler envelopeBuildSampler = UnityEngine.Profiling.CustomSampler.Create ("JSON_EnvelopeBuilding");
    20                 private static readonly UnityEngine.Profiling.CustomSampler netWriteSampler = UnityEngine.Profiling.CustomSampler.Create ("JSON_Write");
     27                private static readonly CustomSampler envelopeBuildSampler = CustomSampler.Create ("JSON_EnvelopeBuilding");
     28                private static readonly CustomSampler netWriteSampler = CustomSampler.Create ("JSON_Write");
    2129
    2230                public static void WriteText (HttpListenerResponse _resp, string _text, HttpStatusCode _statusCode = HttpStatusCode.OK, string _mimeType = null) {
     
    5664                }
    5765               
    58                
     66                public static readonly byte[] JsonEmptyData;
     67
    5968                private static readonly byte[] jsonRawDataKey = JsonWriter.GetEncodedPropertyNameWithBeginObject ("data"); // {"data":
    6069
     
    117126                }
    118127
     128                public static void SendEmptyResponse (RequestContext _context, HttpStatusCode _statusCode = HttpStatusCode.OK, byte[] _jsonInputData = null, string _errorCode = null, Exception _exception = null) {
     129                        PrepareEnvelopedResult (out JsonWriter writer);
     130                        writer.WriteRaw (JsonEmptyData);
     131                        SendEnvelopedResult (_context, ref writer, _statusCode, _jsonInputData, _errorCode, _exception);
     132                }
     133
     134
    119135                public static bool TryGetValue (this NameValueCollection _nameValueCollection, string _name, out string _result) {
    120136                        _result = _nameValueCollection [_name];
  • binary-improvements2/bin/Mods/TFP_CommandExtensions/ModInfo.xml

    r432 r434  
    55        <Description value="Additional commands for server operation" />
    66        <Author value="The Fun Pimps LLC" />
    7         <Version value="21.0.280.0" />
     7        <Version value="21.0.288.0" />
    88        <Website value="" />
    99</xml>
  • binary-improvements2/bin/Mods/TFP_MapRendering/ModInfo.xml

    r432 r434  
    55        <Description value="Render the game map to image map tiles as it is uncovered" />
    66        <Author value="The Fun Pimps LLC" />
    7         <Version value="21.0.280.0" />
     7        <Version value="21.0.288.0" />
    88        <Website value="" />
    99</xml>
  • binary-improvements2/bin/Mods/TFP_WebServer/ModInfo.xml

    r432 r434  
    55        <Description value="Integrated Webserver for the Web Dashboard and server APIs" />
    66        <Author value="The Fun Pimps LLC" />
    7         <Version value="21.0.280.0" />
     7        <Version value="21.0.288.0" />
    88        <Website value="" />
    99</xml>
  • binary-improvements2/bin/Mods/Xample_MarkersMod/ModInfo.xml

    r432 r434  
    55        <Description value="Allows placing custom markers on the web map" />
    66        <Author value="Catalysm and Alloc" />
    7         <Version value="21.0.280.0" />
     7        <Version value="21.0.288.0" />
    88        <Website value="" />
    99</xml>
Note: See TracChangeset for help on using the changeset viewer.