Changeset 402
- Timestamp:
- Jan 27, 2023, 7:28:00 PM (2 years ago)
- Location:
- binary-improvements2
- Files:
-
- 4 added
- 5 deleted
- 56 edited
- 1 copied
- 15 moved
Legend:
- Unmodified
- Added
- Removed
-
binary-improvements2/7dtd-binaries/README.txt
r378 r402 2 2 - Assembly-CSharp.dll 3 3 - Assembly-CSharp-firstpass.dll 4 - com.rlabrecque.steamworks.net.dll 4 5 - LogLibrary.dll 5 6 - mscorlib.dll … … 9 10 - UnityEngine.dll 10 11 - UnityEngine.ImageConversionModule.dll 12 - Utf8Json.dll -
binary-improvements2/7dtd-server-fixes/7dtd-server-fixes.csproj
r392 r402 89 89 <ItemGroup> 90 90 <Compile Include="src\AssemblyInfo.cs" /> 91 <Compile Include="src\FileCache\InvalidateCachesCmd.cs" />92 <Compile Include="src\JSON\JsonManualBuilder.cs" />93 <Compile Include="src\LiveData\Animals.cs" />94 <Compile Include="src\LiveData\Hostiles.cs" />95 91 <Compile Include="src\PersistentData\PersistentContainer.cs" /> 96 92 <Compile Include="src\PersistentData\InvItem.cs" /> … … 98 94 <Compile Include="src\PersistentData\Players.cs" /> 99 95 <Compile Include="src\PersistentData\Player.cs" /> 100 <Compile Include="src\JSON\JsonNode.cs" />101 <Compile Include="src\JSON\JsonArray.cs" />102 <Compile Include="src\JSON\JsonObject.cs" />103 <Compile Include="src\JSON\JsonNumber.cs" />104 <Compile Include="src\JSON\JsonString.cs" />105 <Compile Include="src\JSON\JsonBoolean.cs" />106 <Compile Include="src\JSON\Parser.cs" />107 <Compile Include="src\JSON\JsonNull.cs" />108 <Compile Include="src\JSON\MalformedJSONException.cs" />109 <Compile Include="src\FileCache\AbstractCache.cs" />110 <Compile Include="src\FileCache\DirectAccess.cs" />111 <Compile Include="src\FileCache\SimpleCache.cs" />112 <Compile Include="src\FileCache\MapTileCache.cs" />113 96 <Compile Include="src\ModApi.cs" /> 114 <Compile Include="src\AllocsUtils.cs" />115 97 <Compile Include="src\LandClaimList.cs" /> 116 98 <Compile Include="src\PersistentData\Attributes.cs" /> 117 <Compile Include="src\JSON\JsonValue.cs" />118 <Compile Include="src\LiveData\EntityFilterList.cs" />119 99 </ItemGroup> 120 100 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> … … 122 102 <Folder Include="src\" /> 123 103 <Folder Include="src\PersistentData\" /> 124 <Folder Include="src\FileCache\" />125 104 </ItemGroup> 126 105 <ItemGroup> -
binary-improvements2/7dtd-server-fixes/ModInfo.xml
r391 r402 1 1 <?xml version="1.0" encoding="UTF-8" ?> 2 2 <xml> 3 <ModInfo> 4 <Name value="Server extensions" /> 5 <Description value="Common functions" /> 6 <Author value="The Fun Pimps LLC" /> 7 <Version value="1" /> 8 <Website value="" /> 9 </ModInfo> 3 <Name value="TFP_ServerExtensions" /> 4 <DisplayName value="Server Extensions (base)" /> 5 <Description value="Common functions for other mods" /> 6 <Author value="The Fun Pimps LLC" /> 7 <Version value="21.0" /> 8 <Website value="" /> 10 9 </xml> -
binary-improvements2/7dtd-server-fixes/src/ModApi.cs
r391 r402 30 30 } 31 31 32 Log.Out ("Player connected" + 33 ", entityid=" + _cInfo.entityId + 34 ", name=" + _cInfo.playerName + 35 ", pltfmid=" + (_cInfo.PlatformId?.CombinedString ?? "<unknown>") + 36 ", crossid=" + (_cInfo.CrossplatformId?.CombinedString ?? "<unknown/none>") + 37 ", steamOwner=" + (owner ?? "<unknown/none>") + 38 ", ip=" + _cInfo.ip 32 Log.Out ( 33 $"Player connected, entityid={_cInfo.entityId}, name={_cInfo.playerName}, pltfmid={_cInfo.PlatformId?.CombinedString ?? "<unknown>"}, crossid={_cInfo.CrossplatformId?.CombinedString ?? "<unknown/none>"}, steamOwner={owner ?? "<unknown/none>"}, ip={_cInfo.ip}" 39 34 ); 40 35 } … … 66 61 67 62 if (_cInfo != null) { 68 Log.Out ( "Sent chat hook reply to {0}", _cInfo.InternalId);63 Log.Out ($"Sent chat hook reply to {_cInfo.InternalId}"); 69 64 _cInfo.SendPackage (NetPackageManager.GetPackage<NetPackageChat> ().Setup (EChatType.Whisper, -1, testChatAnswer, "", false, null)); 70 65 } else { 71 Log.Error ( "ChatHookExample: Argument _cInfo null on message: {0}", _msg);66 Log.Error ($"ChatHookExample: Argument _cInfo null on message: {_msg}"); 72 67 } 73 68 -
binary-improvements2/7dtd-server-fixes/src/PersistentData/Inventory.cs
r351 r402 67 67 68 68 if (_count > maxAllowed) { 69 Log.Out ("Player with ID " + _playerId + " has stack for \"" + name + "\" greater than allowed (" + 70 _count + " > " + maxAllowed + ")"); 69 Log.Out ($"Player with ID {_playerId} has stack for \"{name}\" greater than allowed ({_count} > {maxAllowed})"); 71 70 } 72 71 … … 80 79 item.icon = itemClass.GetIconName (); 81 80 82 item.iconcolor = AllocsUtils.ColorToHex (itemClass.GetIconTint ());81 item.iconcolor = itemClass.GetIconTint ().ToHexCode (); 83 82 84 83 return item; -
binary-improvements2/7dtd-server-fixes/src/PersistentData/PersistentContainer.cs
r391 r402 22 22 23 23 public void Save () { 24 Stream stream = File.Open ( GameIO.GetSaveGameDir () + "/AllocsPeristentData.bin", FileMode.Create);24 Stream stream = File.Open ($"{GameIO.GetSaveGameDir ()}/AllocsPeristentData.bin", FileMode.Create); 25 25 BinaryFormatter bFormatter = new BinaryFormatter (); 26 26 bFormatter.Serialize (stream, this); … … 29 29 30 30 public static bool Load () { 31 if (!File.Exists ( GameIO.GetSaveGameDir () + "/AllocsPeristentData.bin")) {31 if (!File.Exists ($"{GameIO.GetSaveGameDir ()}/AllocsPeristentData.bin")) { 32 32 return false; 33 33 } 34 34 35 35 try { 36 Stream stream = File.Open ( GameIO.GetSaveGameDir () + "/AllocsPeristentData.bin", FileMode.Open);36 Stream stream = File.Open ($"{GameIO.GetSaveGameDir ()}/AllocsPeristentData.bin", FileMode.Open); 37 37 BinaryFormatter bFormatter = new BinaryFormatter (); 38 38 PersistentContainer obj = (PersistentContainer) bFormatter.Deserialize (stream); -
binary-improvements2/7dtd-server-fixes/src/PersistentData/Player.cs
r369 r402 117 117 } 118 118 119 Log.Out ( "Player set to offline: " + platformId);119 Log.Out ($"Player set to offline: {platformId}"); 120 120 lastOnline = DateTime.Now; 121 121 try { … … 133 133 134 134 public void SetOnline (ClientInfo _ci) { 135 Log.Out ( "Player set to online: " + platformId);135 Log.Out ($"Player set to online: {platformId}"); 136 136 clientInfo = _ci; 137 137 entityId = _ci.entityId; -
binary-improvements2/7dtd-server-fixes/src/PersistentData/Players.cs
r391 r402 22 22 } 23 23 24 Log.Out ( "Created new player entry for ID: " + _platformId);24 Log.Out ($"Created new player entry for ID: {_platformId}"); 25 25 Player p = new Player (_platformId); 26 26 Dict.Add (_platformId, p); -
binary-improvements2/CommandExtensions/CommandExtensions.csproj
r392 r402 67 67 </ItemGroup> 68 68 <ItemGroup> 69 <Compile Include="src\Commands\TestLogSpam.cs" /> 69 70 <Compile Include="src\ModApi.cs" /> 70 71 <Compile Include="src\AssemblyInfo.cs" /> -
binary-improvements2/CommandExtensions/ModInfo.xml
r391 r402 1 1 <?xml version="1.0" encoding="UTF-8" ?> 2 2 <xml> 3 <ModInfo> 4 <Name value="Command extensions" /> 5 <Description value="Additional commands for server operation" /> 6 <Author value="The Fun Pimps LLC" /> 7 <Version value="1" /> 8 <Website value="" /> 9 </ModInfo> 3 <Name value="TFP_CommandExtensions" /> 4 <DisplayName value="Server Command Extensions" /> 5 <Description value="Additional commands for server operation" /> 6 <Author value="The Fun Pimps LLC" /> 7 <Version value="21.0" /> 8 <Website value="" /> 10 9 </xml> -
binary-improvements2/CommandExtensions/src/ChatHelpers.cs
r391 r402 10 10 } 11 11 12 _receiver.SendPackage (NetPackageManager.GetPackage<NetPackageChat> ().Setup (EChatType.Whisper, -1, _message, senderName + " (PM)", false, null)); 12 _receiver.SendPackage (NetPackageManager.GetPackage<NetPackageChat> ().Setup (EChatType.Whisper, -1, _message, 13 $"{senderName} (PM)", false, null)); 13 14 string receiverName = _receiver.playerName; 14 SdtdConsole.Instance.Output (15 $"Message to player {(receiverName != null ? "\"" + receiverName + "\"" : "unknownName")} sent with sender \"{senderName}\"");15 receiverName = receiverName != null ? $"\"{receiverName}\"" : "unknownName"; 16 SdtdConsole.Instance.Output ($"Message to player {receiverName} sent with sender \"{senderName}\""); 16 17 } 17 18 } -
binary-improvements2/CommandExtensions/src/Commands/Give.cs
r391 r402 27 27 public override void Execute (List<string> _params, CommandSenderInfo _senderInfo) { 28 28 if (_params.Count != 3 && _params.Count != 4) { 29 SdtdConsole.Instance.Output ("Wrong number of arguments, expected 3 or 4, found " + _params.Count + 30 "."); 29 SdtdConsole.Instance.Output ($"Wrong number of arguments, expected 3 or 4, found {_params.Count}."); 31 30 return; 32 31 } -
binary-improvements2/CommandExtensions/src/Commands/ListItems.cs
r391 r402 39 39 } 40 40 41 SdtdConsole.Instance.Output ( " " + s);41 SdtdConsole.Instance.Output ($" {s}"); 42 42 listed++; 43 43 } 44 44 45 SdtdConsole.Instance.Output ( "Listed " + listed + "matching items.");45 SdtdConsole.Instance.Output ($"Listed {listed} matching items."); 46 46 } 47 47 } -
binary-improvements2/CommandExtensions/src/Commands/ListLandProtection.cs
r391 r402 60 60 userIdFilter = ci.InternalId; 61 61 } else { 62 SdtdConsole.Instance.Output ( "Player name or entity id \"" + _params [0] + "\" not found.");62 SdtdConsole.Instance.Output ($"Player name or entity id \"{_params [0]}\" not found."); 63 63 return; 64 64 } … … 82 82 } catch (Exception e) { 83 83 SdtdConsole.Instance.Output ("Error getting current player's position"); 84 Log.Out ( "Error in ListLandProtection.Run: " + e);84 Log.Out ($"Error in ListLandProtection.Run: {e}"); 85 85 return; 86 86 } … … 114 114 foreach (Vector3i v in claimPositions) { 115 115 if (parseableOutput) { 116 SdtdConsole.Instance.Output ( "LandProtectionOf: id=" + claimOwner.PlatformId +117 ", playerName=" + claimOwner.Name + ", location=" + v);116 SdtdConsole.Instance.Output ( 117 $"LandProtectionOf: id={claimOwner.PlatformId}, playerName={claimOwner.Name}, location={v}"); 118 118 } else { 119 SdtdConsole.Instance.Output ( " (" + v + ")");119 SdtdConsole.Instance.Output ($" ({v})"); 120 120 } 121 121 } … … 123 123 124 124 if (userIdFilter == null) { 125 SdtdConsole.Instance.Output ( "Total of " + ppl.m_lpBlockMap.Count + "keystones in the game");125 SdtdConsole.Instance.Output ($"Total of {ppl.m_lpBlockMap.Count} keystones in the game"); 126 126 } 127 127 } -
binary-improvements2/CommandExtensions/src/Commands/RemoveLandProtection.cs
r391 r402 50 50 GameManager.Instance.SetBlocksRPC (changes); 51 51 52 SdtdConsole.Instance.Output ("Tried to remove #" + changes.Count + 53 " land protection blocks for player \"" + _id + "\". Note " + 54 "that only blocks in chunks that are currently loaded (close to any player) could be removed. " + 55 "Please check for remaining blocks by running:"); 56 SdtdConsole.Instance.Output (" listlandprotection " + _id); 52 SdtdConsole.Instance.Output ( 53 $"Tried to remove #{changes.Count} land protection blocks for player \"{_id}\". Note that only blocks in chunks that are currently loaded (close to any player) could be removed. Please check for remaining blocks by running:"); 54 SdtdConsole.Instance.Output ($" listlandprotection {_id}"); 57 55 } catch (Exception e) { 58 Log.Out ( "Error in RemoveLandProtection.removeById: " + e);56 Log.Out ($"Error in RemoveLandProtection.removeById: {e}"); 59 57 } 60 58 } … … 87 85 GameManager.Instance.SetBlocksRPC (changes); 88 86 89 SdtdConsole.Instance.Output ( "Land protection block at (" + v + ") removed");87 SdtdConsole.Instance.Output ($"Land protection block at ({v}) removed"); 90 88 } 91 89 … … 128 126 } catch (Exception e) { 129 127 SdtdConsole.Instance.Output ("Error removing claims"); 130 Log.Out ( "Error in RemoveLandProtection.Run: " + e);128 Log.Out ($"Error in RemoveLandProtection.Run: {e}"); 131 129 } 132 130 } catch (Exception e) { 133 131 SdtdConsole.Instance.Output ("Error getting current player's position"); 134 Log.Out ( "Error in RemoveLandProtection.Run: " + e);132 Log.Out ($"Error in RemoveLandProtection.Run: {e}"); 135 133 } 136 134 } else if (_params.Count == 1) { -
binary-improvements2/CommandExtensions/src/Commands/ShowInventory.cs
r391 r402 47 47 48 48 if (tag == null) { 49 SdtdConsole.Instance.Output ( "Belt of player " + p.Name + ":");49 SdtdConsole.Instance.Output ($"Belt of player {p.Name}:"); 50 50 } 51 51 … … 56 56 57 57 if (tag == null) { 58 SdtdConsole.Instance.Output ( "Bagpack of player " + p.Name + ":");58 SdtdConsole.Instance.Output ($"Bagpack of player {p.Name}:"); 59 59 } 60 60 … … 65 65 66 66 if (tag == null) { 67 SdtdConsole.Instance.Output ( "Equipment of player " + p.Name + ":");67 SdtdConsole.Instance.Output ($"Equipment of player {p.Name}:"); 68 68 } 69 69 … … 71 71 72 72 if (tag != null) { 73 SdtdConsole.Instance.Output ("tracker_item id=" + p.EntityID + ", tag=" + tag + 74 ", SHOWINVENTORY DONE"); 73 SdtdConsole.Instance.Output ($"tracker_item id={p.EntityID}, tag={tag}, SHOWINVENTORY DONE"); 75 74 } 76 75 } … … 94 93 // Tag defined -> parseable output 95 94 string partsMsg = DoParts (_inv [i].parts, 1, ""); 96 string msg = "tracker_item id=" + _entityId + ", tag=" + _tag + ", location=" + _location + 97 ", slot=" + i + ", item=" + _inv [i].itemName + ", qnty=" + _inv [i].count + 98 ", quality=" + _inv [i].quality + ", parts=(" + partsMsg + ")"; 95 string msg = 96 $"tracker_item id={_entityId}, tag={_tag}, location={_location}, slot={i}, item={_inv [i].itemName}, qnty={_inv [i].count}, quality={_inv [i].quality}, parts=({partsMsg})"; 99 97 SdtdConsole.Instance.Output (msg); 100 98 } … … 140 138 // Tag defined -> parseable output 141 139 string partsMsg = DoParts (_items [slotindices [i]].parts, 1, ""); 142 string msg = "tracker_item id=" + _entityId + ", tag=" + _tag + ", location=" + _location + 143 ", slot=" + _slotname + ", item=" + item.itemName + ", qnty=1, quality=" + 144 item.quality + ", parts=(" + partsMsg + ")"; 140 string msg = 141 $"tracker_item id={_entityId}, tag={_tag}, location={_location}, slot={_slotname}, item={item.itemName}, qnty=1, quality={item.quality}, parts=({partsMsg})"; 145 142 SdtdConsole.Instance.Output (msg); 146 143 } … … 176 173 } 177 174 178 _currentMessage += _parts [i].itemName + "@" + _parts [i].quality;175 _currentMessage += $"{_parts [i].itemName}@{_parts [i].quality}"; 179 176 _currentMessage = DoParts (_parts [i].parts, _indent + 1, _currentMessage); 180 177 } -
binary-improvements2/MapRendering/MapRendering.csproj
r392 r402 83 83 <Private>False</Private> 84 84 </Reference> 85 <Reference Include="Utf8Json, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"> 86 <HintPath>..\7dtd-binaries\Utf8Json.dll</HintPath> 87 <Private>False</Private> 88 </Reference> 85 89 </ItemGroup> 86 90 <ItemGroup> … … 88 92 <Compile Include="src\MapRenderBlockBuffer.cs" /> 89 93 <Compile Include="src\MapRenderer.cs" /> 94 <Compile Include="src\MapTileCache.cs" /> 90 95 <Compile Include="src\ModApi.cs" /> 91 96 <Compile Include="src\AssemblyInfo.cs" /> … … 95 100 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> 96 101 <ItemGroup> 97 <ProjectReference Include="..\7dtd-server-fixes\7dtd-server-fixes.csproj">98 <Project>{81DA7F87-1A66-4920-AADA-6EAF1971F8D0}</Project>99 <Name>7dtd-server-fixes</Name>100 <Private>False</Private>101 </ProjectReference>102 </ItemGroup>103 <ItemGroup>104 102 <None Include="ModInfo.xml"> 105 103 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> 106 104 </None> 107 105 </ItemGroup> 106 <ItemGroup> 107 <ProjectReference Include="..\WebServer\WebServer.csproj"> 108 <Project>{01b5f981-b9fd-4364-8f9e-9127130d2542}</Project> 109 <Name>WebServer</Name> 110 <Private>False</Private> 111 </ProjectReference> 112 </ItemGroup> 108 113 </Project> -
binary-improvements2/MapRendering/ModInfo.xml
r391 r402 1 1 <?xml version="1.0" encoding="UTF-8" ?> 2 2 <xml> 3 <ModInfo> 4 <Name value="TFP_MapRendering" /> 5 <Description value="Render the game map to image map tiles as it is uncovered" /> 6 <Author value="The Fun Pimps LLC" /> 7 <Version value="1" /> 8 <Website value="" /> 9 </ModInfo> 3 <Name value="TFP_MapRendering" /> 4 <DisplayName value="Map Renderer" /> 5 <Description value="Render the game map to image map tiles as it is uncovered" /> 6 <Author value="The Fun Pimps LLC" /> 7 <Version value="21.0" /> 8 <Website value="" /> 10 9 </xml> -
binary-improvements2/MapRendering/src/Commands/EnableRendering.cs
r391 r402 15 15 public override void Execute (List<string> _params, CommandSenderInfo _senderInfo) { 16 16 if (_params.Count != 1) { 17 SdtdConsole.Instance.Output ( "Current state: " + MapRenderer.renderingEnabled);17 SdtdConsole.Instance.Output ($"Current state: {MapRenderer.renderingEnabled}"); 18 18 return; 19 19 } 20 20 21 21 MapRenderer.renderingEnabled = _params [0].Equals ("1"); 22 SdtdConsole.Instance.Output ( "Set live map rendering to " + _params [0].Equals ("1"));22 SdtdConsole.Instance.Output ($"Set live map rendering to {_params [0].Equals ("1")}"); 23 23 } 24 24 } -
binary-improvements2/MapRendering/src/MapRenderBlockBuffer.cs
r391 r402 1 1 using System; 2 2 using System.IO; 3 using AllocsFixes.FileCache;4 3 using Unity.Collections; 5 4 using UnityEngine; … … 21 20 zoomLevel = _level; 22 21 cache = _cache; 23 folderBase = Constants.MapDirectory + "/" + zoomLevel + "/";22 folderBase = $"{Constants.MapDirectory}/{zoomLevel}/"; 24 23 25 24 { … … 52 51 saveTextureToFile (); 53 52 } catch (Exception e) { 54 Log.Warning ( "Exception in MapRenderBlockBuffer.SaveBlock(): " + e);53 Log.Warning ($"Exception in MapRenderBlockBuffer.SaveBlock(): {e}"); 55 54 } 56 55 Profiler.EndSample (); … … 64 63 string folder; 65 64 if (currentBlockMapPos.x != _block.x) { 66 folder = folderBase + _block.x + '/';65 folder = $"{folderBase}{_block.x}/"; 67 66 68 67 Profiler.BeginSample ("LoadBlock.Directory"); … … 73 72 } 74 73 75 string fileName = folder + _block.y + ".png";74 string fileName = $"{folder}{_block.y}.png"; 76 75 Profiler.EndSample (); 77 76 … … 105 104 public Color32[] GetHalfScaled () { 106 105 Profiler.BeginSample ("HalfScaled.ResizeBuffer"); 107 zoomBuffer.Re size (Constants.MapBlockSize, Constants.MapBlockSize);106 zoomBuffer.Reinitialize (Constants.MapBlockSize, Constants.MapBlockSize); 108 107 Profiler.EndSample (); 109 108 … … 156 155 Profiler.BeginSample ("HalfScaledNative.ResizeBuffer"); 157 156 if (zoomBuffer.format != blockMap.format || zoomBuffer.height != Constants.MapBlockSize / 2 || zoomBuffer.width != Constants.MapBlockSize / 2) { 158 zoomBuffer.Re size (Constants.MapBlockSize / 2, Constants.MapBlockSize / 2, blockMap.format, false);157 zoomBuffer.Reinitialize (Constants.MapBlockSize / 2, Constants.MapBlockSize / 2, blockMap.format, false); 159 158 } 160 159 Profiler.EndSample (); … … 206 205 207 206 if (array != null) { 208 Log.Error ( "Map image tile " + _fileName + "has been corrupted, recreating tile");207 Log.Error ($"Map image tile {_fileName} has been corrupted, recreating tile"); 209 208 } 210 209 211 210 if (blockMap.format != Constants.DefaultTextureFormat || blockMap.height != Constants.MapBlockSize || 212 211 blockMap.width != Constants.MapBlockSize) { 213 blockMap.Re size (Constants.MapBlockSize, Constants.MapBlockSize, Constants.DefaultTextureFormat,212 blockMap.Reinitialize (Constants.MapBlockSize, Constants.MapBlockSize, Constants.DefaultTextureFormat, 214 213 false); 215 214 } -
binary-improvements2/MapRendering/src/MapRenderer.cs
r391 r402 5 5 using System.Text; 6 6 using System.Threading; 7 using AllocsFixes.FileCache;8 using AllocsFixes.JSON;9 7 using UnityEngine; 10 8 using UnityEngine.Profiling; 9 using Utf8Json; 10 using Webserver.FileCache; 11 11 using Object = UnityEngine.Object; 12 12 … … 27 27 28 28 private MapRenderer () { 29 Constants.MapDirectory = GameIO.GetSaveGameDir () + "/map"; 30 31 lock (lockObject) { 32 if (!LoadMapInfo ()) { 33 WriteMapInfo (); 34 } 29 Constants.MapDirectory = $"{GameIO.GetSaveGameDir ()}/map"; 30 31 if (!LoadMapInfo ()) { 32 WriteMapInfo (); 35 33 } 36 34 … … 47 45 public static MapRenderer Instance => instance ??= new MapRenderer (); 48 46 49 public static MapTileCache GetTileCache () {47 public static AbstractCache GetTileCache () { 50 48 return Instance.cache; 51 49 } … … 95 93 } 96 94 } catch (Exception e) { 97 Log.Out ( "Exception in MapRendering.RenderSingleChunk(): " + e);95 Log.Out ($"Exception in MapRendering.RenderSingleChunk(): {e}"); 98 96 } 99 97 }, _chunk); … … 161 159 } 162 160 } catch (Exception e) { 163 Log.Out ( "Exception: " + e);161 Log.Out ($"Exception: {e}"); 164 162 } 165 163 } … … 177 175 if (fullMapTexture != null) { 178 176 byte[] array = fullMapTexture.EncodeToPNG (); 179 File.WriteAllBytes ( Constants.MapDirectory + "/map.png", array);177 File.WriteAllBytes ($"{Constants.MapDirectory}/map.png", array); 180 178 Object.Destroy (fullMapTexture); 181 179 } … … 183 181 renderingFullMap = false; 184 182 185 Log.Out ( "Generating map took: " + microStopwatch.ElapsedMilliseconds + "ms");186 Log.Out ( "World extent: " + minPos + " - " + maxPos);183 Log.Out ($"Generating map took: {microStopwatch.ElapsedMilliseconds} ms"); 184 Log.Out ($"World extent: {minPos} - {maxPos}"); 187 185 } 188 186 … … 307 305 308 306 private void WriteMapInfo () { 309 JsonObject mapInfo = new JsonObject (); 310 mapInfo.Add ("blockSize", new JsonNumber (Constants.MapBlockSize)); 311 mapInfo.Add ("maxZoom", new JsonNumber (Constants.Zoomlevels - 1)); 307 JsonWriter writer = new JsonWriter (); 308 writer.WriteBeginObject (); 309 310 writer.WriteString ("blockSize"); 311 writer.WriteNameSeparator (); 312 writer.WriteInt32 (Constants.MapBlockSize); 313 314 writer.WriteValueSeparator (); 315 writer.WriteString ("maxZoom"); 316 writer.WriteNameSeparator (); 317 writer.WriteInt32 (Constants.Zoomlevels - 1); 318 319 writer.WriteEndObject (); 312 320 313 321 Directory.CreateDirectory (Constants.MapDirectory); 314 File.WriteAll Text (Constants.MapDirectory + "/mapinfo.json", mapInfo.ToString (), Encoding.UTF8);322 File.WriteAllBytes ($"{Constants.MapDirectory}/mapinfo.json", writer.ToUtf8ByteArray ()); 315 323 } 316 324 317 325 private bool LoadMapInfo () { 318 if (!File.Exists ( Constants.MapDirectory + "/mapinfo.json")) {326 if (!File.Exists ($"{Constants.MapDirectory}/mapinfo.json")) { 319 327 return false; 320 328 } 321 329 322 string json = File.ReadAllText ( Constants.MapDirectory + "/mapinfo.json", Encoding.UTF8);330 string json = File.ReadAllText ($"{Constants.MapDirectory}/mapinfo.json", Encoding.UTF8); 323 331 try { 324 JsonNode node = Parser.Parse (json); 325 if (node is JsonObject jo) { 326 if (jo.ContainsKey ("blockSize")) { 327 Constants.MapBlockSize = ((JsonNumber) jo ["blockSize"]).GetInt (); 328 } 329 330 if (jo.ContainsKey ("maxZoom")) { 331 Constants.Zoomlevels = ((JsonNumber) jo ["maxZoom"]).GetInt () + 1; 332 } 333 334 return true; 335 } 336 } catch (MalformedJsonException e) { 337 Log.Out ("Exception in LoadMapInfo: " + e); 338 } catch (InvalidCastException e) { 339 Log.Out ("Exception in LoadMapInfo: " + e); 332 IDictionary<string,object> inputJson = JsonSerializer.Deserialize<IDictionary<string, object>> (json); 333 334 if (inputJson.TryGetValue ("blockSize", out object fieldNode) && fieldNode is double value) { 335 Constants.MapBlockSize = (int)value; 336 } 337 338 if (inputJson.TryGetValue ("maxZoom", out fieldNode) && fieldNode is double value2) { 339 Constants.Zoomlevels = (int)value2 + 1; 340 } 341 342 return true; 343 } catch (Exception e) { 344 Log.Out ($"Exception in LoadMapInfo: {e}"); 340 345 } 341 346 -
binary-improvements2/MapRendering/src/MapTileCache.cs
r399 r402 1 1 using System; 2 using System.Diagnostics.CodeAnalysis; 2 3 using System.IO; 3 4 using UnityEngine; 4 5 using UnityEngine.Profiling; 6 using Webserver.FileCache; 5 7 using Object = UnityEngine.Object; 6 8 7 namespace AllocsFixes.FileCache{9 namespace MapRendering { 8 10 // Special "cache" for map tile folder as both map rendering and webserver access files in there. 9 11 // Only map rendering tiles are cached. Writing is done by WriteThrough. … … 25 27 } 26 28 29 // SetZoomCount only called before processing happens in MapRenderer.ctor, no locking required 30 [SuppressMessage ("ReSharper", "InconsistentlySynchronizedField")] 27 31 public void SetZoomCount (int _count) { 28 32 cache = new CurrentZoomFile[_count]; … … 55 59 } 56 60 } catch (Exception e) { 57 Log.Warning ( "Error in MapTileCache.LoadTile: " + e);61 Log.Warning ($"Error in MapTileCache.LoadTile: {e}"); 58 62 } 59 63 … … 81 85 } 82 86 } catch (Exception e) { 83 Log.Warning ( "Error in MapTileCache.SaveTile: " + e);87 Log.Warning ($"Error in MapTileCache.SaveTile: {e}"); 84 88 } 85 89 } … … 92 96 } 93 97 } catch (Exception e) { 94 Log.Warning ( "Error in MapTileCache.ResetTile: " + e);98 Log.Warning ($"Error in MapTileCache.ResetTile: {e}"); 95 99 } 96 100 } … … 108 112 } 109 113 } catch (Exception e) { 110 Log.Warning ( "Error in MapTileCache.GetFileContent: " + e);114 Log.Warning ($"Error in MapTileCache.GetFileContent: {e}"); 111 115 } 112 116 … … 119 123 120 124 private static byte[] ReadAllBytes (string _path) { 121 using (FileStream fileStream = new FileStream(_path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096)) { 122 int bytesRead = 0; 123 int bytesLeft = (int) fileStream.Length; 124 byte[] result = new byte[bytesLeft]; 125 while (bytesLeft > 0) { 126 int readThisTime = fileStream.Read (result, bytesRead, bytesLeft); 127 if (readThisTime == 0) { 128 throw new IOException ("Unexpected end of stream"); 129 } 130 131 bytesRead += readThisTime; 132 bytesLeft -= readThisTime; 125 using FileStream fileStream = new FileStream(_path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096); 126 127 int bytesRead = 0; 128 int bytesLeft = (int) fileStream.Length; 129 byte[] result = new byte[bytesLeft]; 130 while (bytesLeft > 0) { 131 int readThisTime = fileStream.Read (result, bytesRead, bytesLeft); 132 if (readThisTime == 0) { 133 throw new IOException ("Unexpected end of stream"); 133 134 } 134 135 135 return result; 136 bytesRead += readThisTime; 137 bytesLeft -= readThisTime; 136 138 } 139 140 return result; 137 141 } 138 142 -
binary-improvements2/MapRendering/src/ModApi.cs
r391 r402 1 1 using JetBrains.Annotations; 2 using Webserver; 3 using Webserver.UrlHandlers; 2 4 3 5 namespace MapRendering { … … 7 9 ModEvents.GameShutdown.RegisterHandler (GameShutdown); 8 10 ModEvents.CalcChunkColorsDone.RegisterHandler (CalcChunkColorsDone); 11 12 Web.ServerInitialized += _web => { 13 _web.RegisterPathHandler ("/map/", new StaticHandler ( 14 $"{GameIO.GetSaveGameDir ()}/map", 15 MapRenderer.GetTileCache (), 16 false, 17 "web.map") 18 ); 19 }; 9 20 } 10 21 -
binary-improvements2/MarkersMod/MarkersMod.csproj
r392 r402 59 59 <Private>False</Private> 60 60 </Reference> 61 <Reference Include="UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"> 62 <HintPath>..\7dtd-binaries\UnityEngine.CoreModule.dll</HintPath> 63 <Private>False</Private> 64 </Reference> 65 <Reference Include="Utf8Json, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"> 66 <HintPath>..\7dtd-binaries\Utf8Json.dll</HintPath> 67 <Private>False</Private> 68 </Reference> 61 69 </ItemGroup> 62 70 <ItemGroup> … … 72 80 </ItemGroup> 73 81 <ItemGroup> 74 <ProjectReference Include="..\7dtd-server-fixes\7dtd-server-fixes.csproj">75 <Project>{81da7f87-1a66-4920-aada-6eaf1971f8d0}</Project>76 <Name>7dtd-server-fixes</Name>77 <Private>False</Private>78 </ProjectReference>79 82 <ProjectReference Include="..\WebServer\WebServer.csproj"> 80 83 <Project>{01b5f981-b9fd-4364-8f9e-9127130d2542}</Project> -
binary-improvements2/MarkersMod/ModInfo.xml
r390 r402 1 1 <?xml version="1.0" encoding="UTF-8" ?> 2 2 <xml> 3 <ModInfo> 4 <Name value="Markers" /> 5 <Description value="Allows placing custom markers on the web map" /> 6 <Author value="Catalysm and Alloc" /> 7 <Version value="1" /> 8 <Website value="" /> 9 </ModInfo> 3 <Name value="TFP_MarkersExample" /> 4 <DisplayName value="Markers (Example Web Mod)" /> 5 <Description value="Allows placing custom markers on the web map" /> 6 <Author value="Catalysm and Alloc" /> 7 <Version value="21.0" /> 8 <Website value="" /> 10 9 </xml> -
binary-improvements2/MarkersMod/src/Markers.cs
r391 r402 1 1 using System.Collections.Generic; 2 2 using System.Net; 3 using AllocsFixes.JSON; 3 using JetBrains.Annotations; 4 using Utf8Json; 4 5 using Webserver; 5 6 using Webserver.WebAPI; 6 7 7 8 namespace Examples { 9 [UsedImplicitly] 8 10 public class Markers : AbsRestApi { 9 11 private const int numRandomMarkers = 5; … … 11 13 private readonly Dictionary<string, (int, int)> markers = new Dictionary<string, (int, int)> (); 12 14 13 private static readonly JsonArray emptyResult = new JsonArray ();14 15 15 public Markers () { 16 16 GameRandom random = GameRandomManager.Instance.CreateGameRandom (); … … 24 24 } 25 25 26 private static readonly byte[] jsonKeyId = JsonWriter.GetEncodedPropertyNameWithBeginObject ("id"); 27 private static readonly byte[] jsonKeyLat = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("lat"); 28 private static readonly byte[] jsonKeyLng = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("lng"); 29 26 30 protected override void HandleRestGet (RequestContext _context) { 27 31 string id = _context.RequestPath; 28 32 33 PrepareEnvelopedResult (out JsonWriter writer); 34 29 35 if (string.IsNullOrEmpty (id)) { 30 JsonArray result = new JsonArray ();36 writer.WriteBeginArray (); 31 37 38 bool first = true; 32 39 foreach ((string markerId, (int, int) coordinates) in markers) { 33 JsonObject marker = new JsonObject (); 34 marker.Add ("id", new JsonString (markerId)); 35 marker.Add ("lat", new JsonNumber (coordinates.Item1)); 36 marker.Add ("lng", new JsonNumber (coordinates.Item2)); 37 result.Add (marker); 40 if (!first) { 41 writer.WriteValueSeparator (); 42 } 43 44 first = false; 45 46 writeMarkerJson (ref writer, markerId, coordinates); 38 47 } 39 40 SendEnvelopedResult (_context, result); 48 49 writer.WriteEndArray (); 50 SendEnvelopedResult (_context, ref writer); 41 51 return; 42 52 } 43 53 44 54 if (!markers.TryGetValue (id, out (int, int) location)) { 45 SendEnvelopedResult (_context, emptyResult, HttpStatusCode.NotFound); 55 writer.WriteRaw (JsonEmptyData); 56 SendEnvelopedResult (_context, ref writer, HttpStatusCode.NotFound); 46 57 return; 47 58 } 48 59 49 60 { 50 JsonArray result = new JsonArray (); 51 JsonObject marker = new JsonObject (); 52 marker.Add ("id", new JsonString (id)); 53 marker.Add ("lat", new JsonNumber (location.Item1)); 54 marker.Add ("lng", new JsonNumber (location.Item2)); 55 result.Add (marker); 56 SendEnvelopedResult (_context, result); 61 writer.WriteBeginArray (); 62 63 writeMarkerJson (ref writer, id, location); 64 65 writer.WriteEndArray (); 66 SendEnvelopedResult (_context, ref writer); 57 67 } 58 68 } 59 69 60 protected override void HandleRestPost (RequestContext _context, JsonNode _jsonBody) { 61 if (!(_jsonBody is JsonObject bodyObject)) { 62 SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, _jsonBody, "BODY_NOT_OBJECT"); 70 private void writeMarkerJson (ref JsonWriter _writer, string _markerId, (int, int) _coordinates) { 71 _writer.WriteRaw (jsonKeyId); 72 _writer.WriteString (_markerId); 73 _writer.WriteRaw (jsonKeyLat); 74 _writer.WriteInt32 (_coordinates.Item1); 75 _writer.WriteRaw (jsonKeyLng); 76 _writer.WriteInt32 (_coordinates.Item2); 77 _writer.WriteEndObject (); 78 } 79 80 protected override void HandleRestPost (RequestContext _context, IDictionary<string, object> _jsonInput, byte[] _jsonInputData) { 81 if (!TryGetJsonField (_jsonInput, "lat", out int lat)) { 82 SendErrorResult (_context, HttpStatusCode.BadRequest, _jsonInputData, "NO_OR_INVALID_LAT"); 63 83 return; 64 84 } 65 85 66 if (!TryGetJsonField (bodyObject, "lat", out int lat)) { 67 SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, _jsonBody, "NO_OR_INVALID_LAT"); 68 return; 69 } 70 71 if (!TryGetJsonField (bodyObject, "lng", out int lng)) { 72 SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, _jsonBody, "NO_OR_INVALID_LNG"); 86 if (!TryGetJsonField (_jsonInput, "lng", out int lng)) { 87 SendErrorResult (_context, HttpStatusCode.BadRequest, _jsonInputData, "NO_OR_INVALID_LNG"); 73 88 return; 74 89 } … … 77 92 markers.Add (newId, (lat, lng)); 78 93 79 JsonString result = new JsonString (newId); 80 SendEnvelopedResult (_context, result, HttpStatusCode.Created); 94 PrepareEnvelopedResult (out JsonWriter writer); 95 writer.WriteString (newId); 96 SendEnvelopedResult (_context, ref writer, HttpStatusCode.Created); 81 97 } 82 98 83 protected override void HandleRestPut (RequestContext _context, JsonNode _jsonBody) {84 if (! (_jsonBody is JsonObject bodyObject)) {85 SendE nvelopedResult (_context, null, HttpStatusCode.BadRequest, _jsonBody, "BODY_NOT_OBJECT");99 protected override void HandleRestPut (RequestContext _context, IDictionary<string, object> _jsonInput, byte[] _jsonInputData) { 100 if (!TryGetJsonField (_jsonInput, "lat", out int lat)) { 101 SendErrorResult (_context, HttpStatusCode.BadRequest, _jsonInputData, "NO_OR_INVALID_LAT"); 86 102 return; 87 103 } 88 104 89 if (!TryGetJsonField (bodyObject, "lat", out int lat)) { 90 SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, _jsonBody, "NO_OR_INVALID_LAT"); 91 return; 92 } 93 94 if (!TryGetJsonField (bodyObject, "lng", out int lng)) { 95 SendEnvelopedResult (_context, null, HttpStatusCode.BadRequest, _jsonBody, "NO_OR_INVALID_LNG"); 105 if (!TryGetJsonField (_jsonInput, "lng", out int lng)) { 106 SendErrorResult (_context, HttpStatusCode.BadRequest, _jsonInputData, "NO_OR_INVALID_LNG"); 96 107 return; 97 108 } … … 100 111 101 112 if (!markers.TryGetValue (id, out _)) { 102 SendE nvelopedResult (_context, null, HttpStatusCode.NotFound, _jsonBody, "ID_NOT_FOUND");113 SendErrorResult (_context, HttpStatusCode.NotFound, _jsonInputData, "ID_NOT_FOUND"); 103 114 return; 104 115 } … … 106 117 markers [id] = (lat, lng); 107 118 108 JsonObject result = new JsonObject (); 109 result.Add ("id", new JsonString (id)); 110 result.Add ("lat", new JsonNumber (lat)); 111 result.Add ("lng", new JsonNumber (lng)); 112 SendEnvelopedResult (_context, result); 119 PrepareEnvelopedResult (out JsonWriter writer); 120 writer.WriteRaw (jsonKeyId); 121 writer.WriteString (id); 122 writer.WriteRaw (jsonKeyLat); 123 writer.WriteInt32 (lat); 124 writer.WriteRaw (jsonKeyLng); 125 writer.WriteInt32 (lng); 126 writer.WriteEndObject (); 127 SendEnvelopedResult (_context, ref writer); 113 128 } 114 129 … … 116 131 string id = _context.RequestPath; 117 132 118 SendEnvelopedResult (_context, null, markers.Remove (id) ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); 133 PrepareEnvelopedResult (out JsonWriter writer); 134 writer.WriteRaw (JsonEmptyData); 135 SendEnvelopedResult (_context, ref writer, markers.Remove (id) ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); 119 136 } 120 137 } -
binary-improvements2/MarkersMod/src/ModApi.cs
r391 r402 1 using JetBrains.Annotations; 2 1 3 namespace Examples { 4 [UsedImplicitly] 2 5 public class ModApi : IModApi { 3 6 public void InitMod (Mod _modInstance) { -
binary-improvements2/WebServer/ModInfo.xml
r391 r402 1 1 <?xml version="1.0" encoding="UTF-8" ?> 2 2 <xml> 3 <ModInfo> 4 <Name value="TFP WebServer" /> 5 <Description value="WebServer implementation" /> 6 <Author value="The Fun Pimps LLC" /> 7 <Version value="1" /> 8 <Website value="" /> 9 </ModInfo> 3 <Name value="TFP_WebServer" /> 4 <DisplayName value="Web Dashboard" /> 5 <Description value="Integrated Webserver for the Web Dashboard and server APIs" /> 6 <Author value="The Fun Pimps LLC" /> 7 <Version value="21.0" /> 8 <Website value="" /> 10 9 </xml> -
binary-improvements2/WebServer/WebServer.csproj
r392 r402 11 11 <AssemblyName>WebServer</AssemblyName> 12 12 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> 13 <LangVersion> 8</LangVersion>13 <LangVersion>9</LangVersion> 14 14 </PropertyGroup> 15 15 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> … … 45 45 <Reference Include="Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"> 46 46 <HintPath>..\7dtd-binaries\Assembly-CSharp-firstpass.dll</HintPath> 47 <Private>False</Private> 48 </Reference> 49 <Reference Include="com.rlabrecque.steamworks.net, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"> 50 <HintPath>..\7dtd-binaries\com.rlabrecque.steamworks.net.dll</HintPath> 47 51 <Private>False</Private> 48 52 </Reference> … … 83 87 <Private>False</Private> 84 88 </Reference> 89 <Reference Include="Utf8Json, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"> 90 <HintPath>..\7dtd-binaries\Utf8Json.dll</HintPath> 91 <Private>False</Private> 92 </Reference> 85 93 </ItemGroup> 86 94 <ItemGroup> 95 <Compile Include="src\FileCache\AbstractCache.cs" /> 96 <Compile Include="src\FileCache\DirectAccess.cs" /> 97 <Compile Include="src\FileCache\InvalidateCachesCmd.cs" /> 98 <Compile Include="src\FileCache\SimpleCache.cs" /> 99 <Compile Include="src\LiveData\Animals.cs" /> 100 <Compile Include="src\LiveData\EntityFilterList.cs" /> 101 <Compile Include="src\LiveData\Hostiles.cs" /> 87 102 <Compile Include="src\ModApi.cs" /> 88 103 <Compile Include="src\UrlHandlers\ApiHandler.cs" /> … … 90 105 <Compile Include="src\WebAPI\AbsRestApi.cs" /> 91 106 <Compile Include="src\WebAPI\AbsWebAPI.cs" /> 92 <Compile Include="src\WebAPI\ ExecuteConsoleCommand.cs" />93 <Compile Include="src\WebAPI\ GetAllowedCommands.cs" />94 <Compile Include="src\WebAPI\ GetAnimalsLocation.cs" />95 <Compile Include="src\WebAPI\ GetHostileLocation.cs" />96 <Compile Include="src\WebAPI\ GetLandClaims.cs" />97 <Compile Include="src\WebAPI\ GetLog.cs" />98 <Compile Include="src\WebAPI\ GetPlayerInventories.cs" />99 <Compile Include="src\WebAPI\ GetPlayerInventory.cs" />100 <Compile Include="src\WebAPI\ GetPlayerList.cs" />101 <Compile Include="src\WebAPI\ GetPlayersLocation.cs" />102 <Compile Include="src\WebAPI\ GetPlayersOnline.cs" />103 <Compile Include="src\WebAPI\ GetServerInfo.cs" />104 <Compile Include="src\WebAPI\ GetStats.cs" />105 <Compile Include="src\WebAPI\ GetWebMods.cs" />106 <Compile Include="src\WebAPI\ GetWebUIUpdates.cs" />107 <Compile Include="src\WebAPI\APIs\Animal.cs" /> 108 <Compile Include="src\WebAPI\APIs\Command.cs" /> 109 <Compile Include="src\WebAPI\APIs\GetLandClaims.cs" /> 110 <Compile Include="src\WebAPI\APIs\GetPlayerInventories.cs" /> 111 <Compile Include="src\WebAPI\APIs\GetPlayerInventory.cs" /> 112 <Compile Include="src\WebAPI\APIs\GetPlayerList.cs" /> 113 <Compile Include="src\WebAPI\APIs\GetPlayersLocation.cs" /> 114 <Compile Include="src\WebAPI\APIs\GetPlayersOnline.cs" /> 115 <Compile Include="src\WebAPI\APIs\Hostile.cs" /> 116 <Compile Include="src\WebAPI\APIs\Log.cs" /> 117 <Compile Include="src\WebAPI\APIs\ServerInfo.cs" /> 118 <Compile Include="src\WebAPI\APIs\ServerStats.cs" /> 119 <Compile Include="src\WebAPI\APIs\WebMods.cs" /> 120 <Compile Include="src\WebAPI\APIs\WebUiUpdates.cs" /> 121 <Compile Include="src\WebAPI\JsonCommons.cs" /> 107 122 <Compile Include="src\WebAPI\Null.cs" /> 108 123 <Compile Include="src\AssemblyInfo.cs" /> … … 145 160 </ItemGroup> 146 161 <ItemGroup> 147 <ProjectReference Include="..\7dtd-server-fixes\7dtd-server-fixes.csproj">148 <Project>{81da7f87-1a66-4920-aada-6eaf1971f8d0}</Project>149 <Name>7dtd-server-fixes</Name>150 <Private>False</Private>151 </ProjectReference>152 <ProjectReference Include="..\MapRendering\MapRendering.csproj">153 <Project>{a1847b5f-7bfc-4bcd-94aa-a6c9fb7e7c54}</Project>154 <Name>MapRendering</Name>155 <Private>False</Private>156 </ProjectReference>157 162 <ProjectReference Include="..\SpaceWizards.HttpListener\SpaceWizards.HttpListener.csproj"> 158 163 <Project>{1c5368e1-a4cf-4580-86bb-dffb20ab682c}</Project> -
binary-improvements2/WebServer/src/Commands/EnableOpenIDDebug.cs
r391 r402 15 15 public override void Execute (List<string> _params, CommandSenderInfo _senderInfo) { 16 16 if (_params.Count != 1) { 17 SdtdConsole.Instance.Output ( "Current state: " + OpenID.debugOpenId);17 SdtdConsole.Instance.Output ($"Current state: {OpenID.debugOpenId}"); 18 18 return; 19 19 } 20 20 21 21 OpenID.debugOpenId = _params [0].Equals ("1"); 22 SdtdConsole.Instance.Output ( "Set OpenID debugging to " + _params [0].Equals ("1"));22 SdtdConsole.Instance.Output ($"Set OpenID debugging to {_params [0].Equals ("1")}"); 23 23 } 24 24 } -
binary-improvements2/WebServer/src/Commands/WebTokens.cs
r391 r402 33 33 ExecuteList (); 34 34 } else { 35 SdtdConsole.Instance.Output ( "Invalid sub command \"" + _params [0] + "\".");35 SdtdConsole.Instance.Output ($"Invalid sub command \"{_params [0]}\"."); 36 36 } 37 37 } else { … … 42 42 private void ExecuteAdd (List<string> _params) { 43 43 if (_params.Count != 4) { 44 SdtdConsole.Instance.Output ( "Wrong number of arguments, expected 4, found " + _params.Count + ".");44 SdtdConsole.Instance.Output ($"Wrong number of arguments, expected 4, found {_params.Count}."); 45 45 return; 46 46 } … … 79 79 private void ExecuteRemove (List<string> _params) { 80 80 if (_params.Count != 2) { 81 SdtdConsole.Instance.Output ( "Wrong number of arguments, expected 2, found " + _params.Count + ".");81 SdtdConsole.Instance.Output ($"Wrong number of arguments, expected 2, found {_params.Count}."); 82 82 return; 83 83 } -
binary-improvements2/WebServer/src/ConnectionHandler.cs
r391 r402 2 2 using System.Collections.Generic; 3 3 using System.Net; 4 using Platform.Steam;5 4 6 5 namespace Webserver { … … 19 18 20 19 if (!Equals (con.Endpoint, _ip)) { 21 // Fixed: Allow different clients from same NAT network 22 // connections.Remove (_sessionId); 20 connections.Remove (_sessionId); 23 21 return null; 24 22 } … … 33 31 } 34 32 35 public WebConnection LogIn ( ulong _steamId, IPAddress _ip) {33 public WebConnection LogIn (PlatformUserIdentifierAbs _userId, IPAddress _ip) { 36 34 string sessionId = Guid.NewGuid ().ToString (); 37 PlatformUserIdentifierAbs userId = new UserIdentifierSteam (_steamId); 38 WebConnection con = new WebConnection (sessionId, _ip, userId); 35 WebConnection con = new WebConnection (sessionId, _ip, _userId); 39 36 connections.Add (sessionId, con); 40 37 return con; -
binary-improvements2/WebServer/src/FileCache/AbstractCache.cs
r392 r402 1 1 using System.Collections.Generic; 2 2 3 namespace AllocsFixes.FileCache {3 namespace Webserver.FileCache { 4 4 public abstract class AbstractCache { 5 5 public abstract byte[] GetFileContent (string _filename); 6 public abstract (int , int) Invalidate ();6 public abstract (int filesDropped, int bytesDropped) Invalidate (); 7 7 8 8 protected AbstractCache () { … … 16 16 17 17 foreach (AbstractCache cache in caches) { 18 (int , int) returned= cache.Invalidate ();19 filesDropped += returned.Item1;20 bytesDropped += returned.Item2;18 (int files, int bytes) = cache.Invalidate (); 19 filesDropped += files; 20 bytesDropped += bytes; 21 21 } 22 22 -
binary-improvements2/WebServer/src/FileCache/DirectAccess.cs
r392 r402 2 2 using System.IO; 3 3 4 namespace AllocsFixes.FileCache {4 namespace Webserver.FileCache { 5 5 // Not caching at all, simply reading from disk on each request 6 6 public class DirectAccess : AbstractCache { … … 9 9 return File.Exists (_filename) ? File.ReadAllBytes (_filename) : null; 10 10 } catch (Exception e) { 11 Log.Out ( "Error in DirectAccess.GetFileContent: " + e);11 Log.Out ($"Error in DirectAccess.GetFileContent: {e}"); 12 12 } 13 13 -
binary-improvements2/WebServer/src/FileCache/InvalidateCachesCmd.cs
r397 r402 2 2 using JetBrains.Annotations; 3 3 4 namespace AllocsFixes.FileCache {4 namespace Webserver.FileCache { 5 5 [UsedImplicitly] 6 6 public class InvalidateCachesCmd : ConsoleCmdAbstract { -
binary-improvements2/WebServer/src/FileCache/SimpleCache.cs
r392 r402 3 3 using System.IO; 4 4 5 namespace AllocsFixes.FileCache {5 namespace Webserver.FileCache { 6 6 // Caching all files, useful for completely static folders only 7 7 public class SimpleCache : AbstractCache { … … 24 24 } 25 25 } catch (Exception e) { 26 Log.Out ( "Error in SimpleCache.GetFileContent: " + e);26 Log.Out ($"Error in SimpleCache.GetFileContent: {e}"); 27 27 } 28 28 -
binary-improvements2/WebServer/src/LiveData/Animals.cs
r326 r402 1 namespace AllocsFixes.LiveData {1 namespace Webserver.LiveData { 2 2 public class Animals : EntityFilterList<EntityAnimal> { 3 3 public static readonly Animals Instance = new Animals (); 4 4 5 5 protected override EntityAnimal predicate (Entity _e) { 6 EntityAnimal ea = _e as EntityAnimal; 7 if (ea != null && ea.IsAlive ()) { 6 if (_e is EntityAnimal ea && ea.IsAlive ()) { 8 7 return ea; 9 8 } -
binary-improvements2/WebServer/src/LiveData/EntityFilterList.cs
r325 r402 2 2 using System.Collections.Generic; 3 3 4 namespace AllocsFixes.LiveData {4 namespace Webserver.LiveData { 5 5 public abstract class EntityFilterList<T> where T : Entity { 6 6 public void Get (List<T> _list) { -
binary-improvements2/WebServer/src/LiveData/Hostiles.cs
r326 r402 1 namespace AllocsFixes.LiveData {1 namespace Webserver.LiveData { 2 2 public class Hostiles : EntityFilterList<EntityEnemy> { 3 3 public static readonly Hostiles Instance = new Hostiles (); 4 4 5 5 protected override EntityEnemy predicate (Entity _e) { 6 EntityEnemy enemy = _e as EntityEnemy; 7 if (enemy != null && enemy.IsAlive ()) { 6 if (_e is EntityEnemy enemy && enemy.IsAlive ()) { 8 7 return enemy; 9 8 } -
binary-improvements2/WebServer/src/MimeType.cs
r391 r402 574 574 575 575 if (!_extension.StartsWith (".")) { 576 _extension = "." + _extension;576 _extension = $".{_extension}"; 577 577 } 578 578 -
binary-improvements2/WebServer/src/OpenID.cs
r399 r402 19 19 20 20 private static readonly X509Certificate2 caCert = 21 new X509Certificate2 (Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location) + 22 "/steam-rootca.cer"); 21 new X509Certificate2 ($"{Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location)}/steam-rootca.cer"); 23 22 24 23 private static readonly X509Certificate2 caIntermediateCert = 25 new X509Certificate2 (Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location) + 26 "/steam-intermediate.cer"); 24 new X509Certificate2 ($"{Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location)}/steam-intermediate.cer"); 27 25 28 26 private const bool verboseSsl = false; … … 74 72 foreach (X509ChainElement chainEl in privateChain.ChainElements) { 75 73 if (verboseSsl) { 76 Log.Out ( "Validating cert: " + chainEl.Certificate.Subject);74 Log.Out ($"Validating cert: {chainEl.Certificate.Subject}"); 77 75 } 78 76 … … 80 78 foreach (X509ChainStatus chainStatus in chainEl.ChainElementStatus) { 81 79 if (verboseSsl) { 82 Log.Out ( " Status: " + chainStatus.Status);80 Log.Out ($" Status: {chainStatus.Status}"); 83 81 } 84 82 … … 94 92 95 93 // This status is an error, print information 96 Log.Warning ("[OpenID] Steam certificate error: " + chainEl.Certificate.Subject + " ### Error: " + 97 chainStatus.Status); 94 Log.Warning ($"[OpenID] Steam certificate error: {chainEl.Certificate.Subject} ### Error: {chainStatus.Status}"); 98 95 privateChain.Reset (); 99 96 return false; … … 104 101 if (chainStatus.Status != X509ChainStatusFlags.NoError && 105 102 chainStatus.Status != X509ChainStatusFlags.UntrustedRoot) { 106 Log.Warning ( "[OpenID] Steam certificate error: " + chainStatus.Status);103 Log.Warning ($"[OpenID] Steam certificate error: {chainStatus.Status}"); 107 104 privateChain.Reset (); 108 105 return false; … … 130 127 }; 131 128 132 return STEAM_LOGIN + '?' + buildUrlParams (queryParams);129 return $"{STEAM_LOGIN}?{buildUrlParams (queryParams)}"; 133 130 } 134 131 … … 141 138 142 139 if (mode == "error") { 143 Log.Warning ( "[OpenID] Steam OpenID login error: " + getValue (_req, "openid.error"));140 Log.Warning ($"[OpenID] Steam OpenID login error: {getValue (_req, "openid.error")}"); 144 141 if (debugOpenId) { 145 142 PrintOpenIdResponse (_req); … … 174 171 string[] signeds = getValue (_req, "openid.signed").Split (','); 175 172 foreach (string s in signeds) { 176 queryParams ["openid." + s] = getValue (_req, "openid." + s); 173 string name = $"openid.{s}"; 174 queryParams [name] = getValue (_req, name); 177 175 } 178 176 … … 201 199 } 202 200 203 Log.Warning ( "[OpenID] Steam OpenID login failed: {0}", responseString);201 Log.Warning ($"[OpenID] Steam OpenID login failed: {responseString}"); 204 202 return 0; 205 203 } … … 209 207 int i = 0; 210 208 foreach ((string argName, string argValue) in _queryParams) { 211 paramsArr [i++] = argName + "=" + Uri.EscapeDataString (argValue);209 paramsArr [i++] = $"{argName}={Uri.EscapeDataString (argValue)}"; 212 210 } 213 211 … … 218 216 NameValueCollection nvc = _req.QueryString; 219 217 if (nvc [_name] == null) { 220 throw new MissingMemberException ( "[OpenID] OpenID parameter \"" + _name + "\" missing");218 throw new MissingMemberException ($"[OpenID] OpenID parameter \"{_name}\" missing"); 221 219 } 222 220 … … 227 225 NameValueCollection nvc = _req.QueryString; 228 226 for (int i = 0; i < nvc.Count; i++) { 229 Log.Out ( " " + nvc.GetKey (i) + " = " + nvc [i]);227 Log.Out ($" {nvc.GetKey (i)} = {nvc [i]}"); 230 228 } 231 229 } -
binary-improvements2/WebServer/src/SSE/AbsEvent.cs
r399 r402 4 4 using System.Net.Sockets; 5 5 using System.Text; 6 using AllocsFixes.JSON;7 6 using Webserver.UrlHandlers; 8 7 using HttpListenerResponse = SpaceWizards.HttpListener.HttpListenerResponse; … … 20 19 private readonly List<HttpListenerResponse> openStreams = new List<HttpListenerResponse> (); 21 20 22 private readonly BlockingQueue<(string _eventName, object_data)> sendQueue =23 new BlockingQueue<(string _eventName, object_data)> ();21 private readonly BlockingQueue<(string _eventName, string _data)> sendQueue = 22 new BlockingQueue<(string _eventName, string _data)> (); 24 23 25 24 private int currentlyOpen; … … 42 41 } 43 42 44 protected void SendData (string _eventName, object_data) {43 protected void SendData (string _eventName, string _data) { 45 44 sendQueue.Enqueue ((_eventName, _data)); 46 45 Parent.SignalSendQueue (); 47 46 } 48 47 49 50 48 public void ProcessSendQueue () { 51 49 while (sendQueue.HasData ()) { 52 (string eventName, objectdata) = sendQueue.Dequeue ();50 (string eventName, string data) = sendQueue.Dequeue (); 53 51 54 52 stringBuilder.Append ("event: "); 55 53 stringBuilder.AppendLine (eventName); 56 54 stringBuilder.Append ("data: "); 57 58 switch (data) { 59 case string dataString: 60 stringBuilder.AppendLine (dataString); 61 break; 62 case JsonNode dataJson: 63 dataJson.ToString (stringBuilder); 64 stringBuilder.AppendLine (""); 65 break; 66 default: 67 logError ("Data is neither string nor JSON.", false); 68 continue; 69 } 55 stringBuilder.AppendLine (data); 70 56 71 57 stringBuilder.AppendLine (""); 58 72 59 string output = stringBuilder.ToString (); 73 60 stringBuilder.Clear (); … … 111 98 if (e.InnerException is SocketException se) { 112 99 if (se.SocketErrorCode != SocketError.ConnectionAborted && se.SocketErrorCode != SocketError.Shutdown) { 113 logError ($"SocketError ({se.SocketErrorCode }) while trying to write", true);100 logError ($"SocketError ({se.SocketErrorCode.ToStringCached ()}) while trying to write", true); 114 101 } 115 102 } else { -
binary-improvements2/WebServer/src/SSE/EventLog.cs
r391 r402 1 1 using System; 2 using AllocsFixes.JSON;3 2 using JetBrains.Annotations; 4 3 using UnityEngine; 4 using Utf8Json; 5 5 using Webserver.UrlHandlers; 6 6 … … 12 12 } 13 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"); 19 14 20 private void LogCallback (string _formattedMsg, string _plainMsg, string _trace, LogType _type, DateTime _timestamp, long _uptime) { 15 21 string isotime = _timestamp.ToString ("o"); 16 22 string uptime = _uptime.ToString (); 17 23 18 JsonObject data = new JsonObject (); 19 data.Add ("msg", new JsonString (_plainMsg)); 20 data.Add ("type", new JsonString (_type.ToStringCached ())); 21 data.Add ("trace", new JsonString (_trace)); 22 data.Add ("isotime", new JsonString (isotime)); 23 data.Add ("uptime", new JsonString (uptime)); 24 25 SendData ("logLine", data); 24 JsonWriter writer = new JsonWriter (); 25 26 writer.WriteRaw (jsonMsgKey); 27 writer.WriteString (_plainMsg); 28 29 writer.WriteRaw (jsonTypeKey); 30 writer.WriteString (_type.ToStringCached ()); 31 32 writer.WriteRaw (jsonTraceKey); 33 writer.WriteString (_trace); 34 35 writer.WriteRaw (jsonIsotimeKey); 36 writer.WriteString (isotime); 37 38 writer.WriteRaw (jsonUptimeKey); 39 writer.WriteString (uptime); 40 41 writer.WriteEndObject (); 42 43 SendData ("logLine", writer.ToString ()); 26 44 } 27 45 } -
binary-improvements2/WebServer/src/UrlHandlers/ApiHandler.cs
r399 r402 45 45 private void addApi (AbsWebAPI _api) { 46 46 apis.Add (_api.Name, _api); 47 WebPermissions.Instance.AddKnownModule ( "webapi." + _api.Name, _api.DefaultPermissionLevel ());47 WebPermissions.Instance.AddKnownModule ($"webapi.{_api.Name}", _api.DefaultPermissionLevel ()); 48 48 } 49 49 … … 92 92 93 93 private bool IsAuthorizedForApi (string _apiName, int _permissionLevel) { 94 return WebPermissions.Instance.ModuleAllowedWithLevel ( "webapi." + _apiName, _permissionLevel);94 return WebPermissions.Instance.ModuleAllowedWithLevel ($"webapi.{_apiName}", _permissionLevel); 95 95 } 96 96 } -
binary-improvements2/WebServer/src/UrlHandlers/ItemIconHandler.cs
r399 r402 3 3 using System.IO; 4 4 using System.Net; 5 using AllocsFixes;6 5 using UnityEngine; 7 6 using Object = UnityEngine.Object; … … 45 44 _context.Response.StatusCode = (int) HttpStatusCode.NotFound; 46 45 if (logMissingFiles) { 47 Log.Out ( "[Web] IconHandler: FileNotFound: \"" + _context.RequestPath + "\" ");46 Log.Out ($"[Web] IconHandler: FileNotFound: \"{_context.RequestPath}\" "); 48 47 } 49 48 } 49 } 50 51 private class LoadingStats { 52 public int Files; 53 public int Tints; 54 public readonly MicroStopwatch MswTotal = new MicroStopwatch (false); 55 public readonly MicroStopwatch MswLoading = new MicroStopwatch (false); 56 public readonly MicroStopwatch MswEncoding = new MicroStopwatch (false); 57 public readonly MicroStopwatch MswTinting = new MicroStopwatch (false); 50 58 } 51 59 … … 57 65 } 58 66 59 MicroStopwatch microStopwatch = new MicroStopwatch (); 67 LoadingStats stats = new LoadingStats (); 68 stats?.MswTotal.Start (); 60 69 61 70 // Get list of used tints for all items … … 72 81 73 82 string name = ic.GetIconName (); 74 if (!tintedIcons.ContainsKey (name)) { 75 tintedIcons.Add (name, new List<Color> ()); 83 if (!tintedIcons.TryGetValue (name, out List<Color> tintsList)) { 84 tintsList = new List<Color> (); 85 tintedIcons.Add (name, tintsList); 76 86 } 77 87 78 List<Color> list = tintedIcons [name]; 79 list.Add (tintColor); 88 tintsList.Add (tintColor); 80 89 } 81 90 82 91 try { 83 loadIconsFromFolder (GameIO.GetGameDir ("Data/ItemIcons"), tintedIcons );92 loadIconsFromFolder (GameIO.GetGameDir ("Data/ItemIcons"), tintedIcons, stats); 84 93 } catch (Exception e) { 85 94 Log.Error ("[Web] Failed loading icons from base game"); … … 90 99 foreach (Mod mod in ModManager.GetLoadedMods ()) { 91 100 try { 92 string modIconsPath = mod.Path + "/ItemIcons";93 loadIconsFromFolder (modIconsPath, tintedIcons );101 string modIconsPath = $"{mod.Path}/ItemIcons"; 102 loadIconsFromFolder (modIconsPath, tintedIcons, stats); 94 103 } catch (Exception e) { 95 Log.Error ( "[Web] Failed loading icons from mod " + mod.ModInfo.Name.Value);104 Log.Error ($"[Web] Failed loading icons from mod {mod.Name}"); 96 105 Log.Exception (e); 97 106 } 98 107 } 108 109 loaded = true; 99 110 100 loaded = true; 101 Log.Out ("[Web] IconHandler: Icons loaded - {0} ms", microStopwatch.ElapsedMilliseconds); 111 if (stats == null) { 112 Log.Out ($"[Web] IconHandler: Loaded {icons.Count} icons"); 113 } else { 114 stats?.MswTotal.Stop (); 115 Log.Out ($"[Web] IconHandler: Loaded {icons.Count} icons ({stats.Files} source images with {stats.Tints} tints applied)"); 116 Log.Out ($"[Web] IconHandler: Total time {stats.MswTotal.ElapsedMilliseconds} ms, loading files {stats.MswLoading.ElapsedMilliseconds} ms, tinting files {stats.MswTinting.ElapsedMilliseconds} ms, encoding files {stats.MswEncoding.ElapsedMilliseconds} ms"); 117 118 int totalSize = 0; 119 foreach ((string _, byte[] iconData) in icons) { 120 totalSize += iconData.Length; 121 } 122 123 Log.Out ($"[Web] IconHandler: Cached {totalSize / 1024} KiB"); 124 } 102 125 103 126 return true; … … 105 128 } 106 129 107 private void loadIconsFromFolder (string _path, Dictionary<string, List<Color>> _tintedIcons ) {130 private void loadIconsFromFolder (string _path, Dictionary<string, List<Color>> _tintedIcons, LoadingStats _stats) { 108 131 if (!Directory.Exists (_path)) { 109 132 return; … … 118 141 string name = Path.GetFileNameWithoutExtension (file); 119 142 Texture2D tex = new Texture2D (1, 1, TextureFormat.ARGB32, false); 120 if (!tex.LoadImage (File.ReadAllBytes (file))) { 143 144 _stats?.MswLoading.Start (); 145 byte[] sourceBytes = File.ReadAllBytes (file); 146 if (!tex.LoadImage (sourceBytes)) { 147 _stats?.MswLoading.Stop (); 121 148 continue; 122 149 } 150 _stats?.MswLoading.Stop (); 123 151 124 AddIcon (name, tex, _tintedIcons);152 AddIcon (name, sourceBytes, tex, _tintedIcons, _stats); 125 153 126 154 Object.Destroy (tex); … … 131 159 } 132 160 133 private void AddIcon (string _name, Texture2D _tex, Dictionary<string, List<Color>> _tintedIcons) { 134 icons [_name + "__FFFFFF"] = _tex.EncodeToPNG (); 161 private void AddIcon (string _name, byte[] _sourceBytes, Texture2D _tex, Dictionary<string, List<Color>> _tintedIcons, LoadingStats _stats) { 162 _stats?.MswEncoding.Start (); 163 icons [$"{_name}__FFFFFF"] = _sourceBytes; 164 _stats?.MswEncoding.Stop (); 135 165 136 if (!_tintedIcons.ContainsKey (_name)) { 166 if (_stats != null) { 167 _stats.Files++; 168 } 169 170 if (!_tintedIcons.TryGetValue (_name, out List<Color> tintsList)) { 137 171 return; 138 172 } 139 173 140 foreach (Color c in _tintedIcons [_name]) {141 string tintedName = _name + "__" + AllocsUtils.ColorToHex (c);174 foreach (Color c in tintsList) { 175 string tintedName = $"{_name}__{c.ToHexCode ()}"; 142 176 if (icons.ContainsKey (tintedName)) { 143 177 continue; … … 146 180 Texture2D tintedTex = new Texture2D (_tex.width, _tex.height, TextureFormat.ARGB32, false); 147 181 148 for (int x = 0; x < _tex.width; x++) { 149 for (int y = 0; y < _tex.height; y++) { 150 tintedTex.SetPixel (x, y, _tex.GetPixel (x, y) * c); 151 } 152 } 182 _stats?.MswTinting.Start (); 183 TextureUtils.ApplyTint (_tex, tintedTex, c); 184 _stats?.MswTinting.Stop (); 153 185 186 _stats?.MswEncoding.Start (); 154 187 icons [tintedName] = tintedTex.EncodeToPNG (); 188 _stats?.MswEncoding.Stop (); 155 189 156 190 Object.Destroy (tintedTex); 191 192 if (_stats != null) { 193 _stats.Tints++; 194 } 157 195 } 158 196 } 197 159 198 } 160 199 } -
binary-improvements2/WebServer/src/UrlHandlers/RewriteHandler.cs
r391 r402 10 10 11 11 public override void HandleRequest (RequestContext _context) { 12 _context.RequestPath = fixedTarget ? target : target + _context.RequestPath.Remove (0, urlBasePath.Length);12 _context.RequestPath = fixedTarget ? target : $"{target}{_context.RequestPath.Remove (0, urlBasePath.Length)}"; 13 13 parent.ApplyPathHandler (_context); 14 14 } -
binary-improvements2/WebServer/src/UrlHandlers/SessionHandler.cs
r399 r402 1 1 using System; 2 using System.Collections.Generic; 3 using System.IO; 2 4 using System.Net; 5 using Platform.Steam; 6 using Utf8Json; 3 7 4 8 namespace Webserver.UrlHandlers { … … 6 10 private const string pageBasePath = "/app"; 7 11 private const string pageErrorPath = "/app/error/"; 12 8 13 private const string steamOpenIdVerifyUrl = "verifysteamopenid"; 9 14 private const string steamLoginUrl = "loginsteam"; 15 private const string userPassLoginUrl = "login"; 10 16 11 17 private readonly ConnectionHandler connectionHandler; … … 37 43 return; 38 44 } 45 46 if (subpath.StartsWith (userPassLoginUrl)) { 47 HandleUserPassLogin (_context); 48 return; 49 } 39 50 40 51 _context.Response.Redirect (pageErrorPath + "InvalidSessionsCommand"); 41 52 } 42 53 54 private void HandleUserPassLogin (RequestContext _context) { 55 if (!_context.Request.HasEntityBody) { 56 _context.Response.Redirect (pageErrorPath + "NoLoginData"); 57 return; 58 } 59 60 Stream requestInputStream = _context.Request.InputStream; 61 62 byte[] jsonInputData = new byte[_context.Request.ContentLength64]; 63 requestInputStream.Read (jsonInputData, 0, (int)_context.Request.ContentLength64); 64 65 IDictionary<string, object> inputJson; 66 try { 67 inputJson = JsonSerializer.Deserialize<IDictionary<string, object>> (jsonInputData); 68 } catch (Exception e) { 69 Log.Error ("Error deserializing JSON from user/password login:"); 70 Log.Exception (e); 71 _context.Response.Redirect (pageErrorPath + "InvalidLoginJson"); 72 return; 73 } 74 75 if (!inputJson.TryGetValue ("username", out object fieldNode) || fieldNode is not string username) { 76 _context.Response.Redirect (pageErrorPath + "InvalidLoginJson"); 77 return; 78 } 79 80 if (!inputJson.TryGetValue ("password", out fieldNode) || fieldNode is not string password) { 81 _context.Response.Redirect (pageErrorPath + "InvalidLoginJson"); 82 return; 83 } 84 85 // TODO: Apply login 86 87 string remoteEndpointString = _context.Request.RemoteEndPoint!.ToString (); 88 89 if (username != "test" || password != "123") { 90 // TODO: failed login 91 Log.Out ($"[Web] User/pass login failed from {remoteEndpointString}"); 92 _context.Response.Redirect (pageErrorPath + "UserPassInvalid"); 93 return; 94 } 95 96 try { 97 // TODO: Match username/password to UserIdentifierAbs / serveradmins.xml 98 99 WebConnection con = connectionHandler.LogIn (new UserIdentifierSteam (76561198066968172ul), _context.Request.RemoteEndPoint.Address); 100 int level = GameManager.Instance.adminTools.GetUserPermissionLevel (con.UserId); 101 Log.Out ($"[Web] User/pass login from {remoteEndpointString} with ID {con.UserId}, permission level {level}"); 102 103 Cookie cookie = new Cookie ("sid", con.SessionID, "/") { 104 Expired = false, 105 Expires = DateTime.MinValue, 106 HttpOnly = true, 107 Secure = false 108 }; 109 _context.Response.AppendCookie (cookie); 110 _context.Response.Redirect (pageBasePath); 111 112 return; 113 } catch (Exception e) { 114 Log.Error ("[Web] Error during user/pass login:"); 115 Log.Exception (e); 116 } 117 118 _context.Response.Redirect (pageErrorPath + "UserPassLoginFailed"); 119 } 120 43 121 private void HandleSteamLogin (RequestContext _context) { 44 string host = (WebUtils.IsSslRedirected (_context.Request) ? "https://" : "http://") + _context.Request.UserHostName;45 string url = OpenID.GetOpenIdLoginUrl (host, host + urlBasePath + steamOpenIdVerifyUrl);122 string host = $"{(WebUtils.IsSslRedirected (_context.Request) ? "https://" : "http://")}{_context.Request.UserHostName}"; 123 string url = OpenID.GetOpenIdLoginUrl (host, $"{host}{urlBasePath}{steamOpenIdVerifyUrl}"); 46 124 _context.Response.Redirect (url); 47 125 } … … 68 146 ulong id = OpenID.Validate (_context.Request); 69 147 if (id > 0) { 70 WebConnection con = connectionHandler.LogIn ( id, _context.Request.RemoteEndPoint.Address);148 WebConnection con = connectionHandler.LogIn (new UserIdentifierSteam (id), _context.Request.RemoteEndPoint.Address); 71 149 int level = GameManager.Instance.adminTools.GetUserPermissionLevel (con.UserId); 72 Log.Out ("[Web] Steam OpenID login from {0} with ID {1}, permission level {2}", 73 remoteEndpointString, con.UserId, level); 150 Log.Out ($"[Web] Steam OpenID login from {remoteEndpointString} with ID {con.UserId}, permission level {level}"); 74 151 75 152 Cookie cookie = new Cookie ("sid", con.SessionID, "/") { -
binary-improvements2/WebServer/src/UrlHandlers/SseHandler.cs
r399 r402 39 39 base.SetBasePathAndParent (_parent, _relativePath); 40 40 41 queueThead = ThreadManager.StartThread ( "SSE-Processing_" + urlBasePath, QueueProcessThread, ThreadPriority.BelowNormal,41 queueThead = ThreadManager.StartThread ($"SSE-Processing_{urlBasePath}", QueueProcessThread, ThreadPriority.BelowNormal, 42 42 _useRealThread: true); 43 43 } … … 49 49 } 50 50 51 // ReSharper disable once MemberCanBePrivate.Global 51 52 public void AddEvent (string _eventName, AbsEvent _eventInstance) { 52 53 events.Add (_eventName, _eventInstance); 53 WebPermissions.Instance.AddKnownModule ( "webevent." + _eventName, _eventInstance.DefaultPermissionLevel ());54 WebPermissions.Instance.AddKnownModule ($"webevent.{_eventName}", _eventInstance.DefaultPermissionLevel ()); 54 55 } 55 56 … … 88 89 89 90 private bool IsAuthorizedForEvent (string _eventName, int _permissionLevel) { 90 return WebPermissions.Instance.ModuleAllowedWithLevel ( "webevent." + _eventName, _permissionLevel);91 return WebPermissions.Instance.ModuleAllowedWithLevel ($"webevent.{_eventName}", _permissionLevel); 91 92 } 92 93 -
binary-improvements2/WebServer/src/UrlHandlers/StaticHandler.cs
r399 r402 1 1 using System.IO; 2 2 using System.Net; 3 using AllocsFixes.FileCache;3 using Webserver.FileCache; 4 4 5 5 namespace Webserver.UrlHandlers { … … 11 11 public StaticHandler (string _filePath, AbstractCache _cache, bool _logMissingFiles, 12 12 string _moduleName = null) : base (_moduleName) { 13 datapath = _filePath + (_filePath [_filePath.Length - 1] == '/' ? "" : "/");13 datapath = $"{_filePath}{(_filePath [^1] == '/' ? "" : "/")}"; 14 14 cache = _cache; 15 15 logMissingFiles = _logMissingFiles; … … 19 19 string fn = _context.RequestPath.Remove (0, urlBasePath.Length); 20 20 21 byte[] content = cache.GetFileContent ( datapath + fn);21 byte[] content = cache.GetFileContent ($"{datapath}{fn}"); 22 22 23 23 if (content != null) { … … 28 28 _context.Response.StatusCode = (int) HttpStatusCode.NotFound; 29 29 if (logMissingFiles) { 30 Log.Warning ( "[Web] Static: FileNotFound: \"" + _context.RequestPath + "\" @ \"" + datapath + fn + "\"");30 Log.Warning ($"[Web] Static: FileNotFound: \"{_context.RequestPath}\" @ \"{datapath}{fn}\""); 31 31 } 32 32 } -
binary-improvements2/WebServer/src/UrlHandlers/UserStatusHandler.cs
r391 r402 1 using AllocsFixes.JSON;1 using Utf8Json; 2 2 3 3 namespace Webserver.UrlHandlers { … … 6 6 } 7 7 8 private static readonly byte[] jsonLoggedInKey = JsonWriter.GetEncodedPropertyNameWithBeginObject ("loggedIn"); 9 private static readonly byte[] jsonUsernameKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("username"); 10 private static readonly byte[] jsonPermissionsKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("permissions"); 11 12 private static readonly byte[] jsonModuleKey = JsonWriter.GetEncodedPropertyNameWithBeginObject ("module"); 13 private static readonly byte[] jsonAllowedKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("allowed"); 14 8 15 public override void HandleRequest (RequestContext _context) { 9 JsonObject result = new JsonObject (); 16 WebUtils.PrepareEnvelopedResult (out JsonWriter writer); 17 18 writer.WriteRaw (jsonLoggedInKey); 19 writer.WriteBoolean (_context.Connection != null); 20 21 writer.WriteRaw (jsonUsernameKey); 22 writer.WriteString (_context.Connection != null ? _context.Connection.UserId.ToString () : string.Empty); 23 24 writer.WriteRaw (jsonPermissionsKey); 25 writer.WriteBeginArray (); 10 26 11 result.Add ("loggedin", new JsonBoolean (_context.Connection != null)); 12 result.Add ("username", new JsonString (_context.Connection != null ? _context.Connection.UserId.ToString () : string.Empty)); 27 bool first = true; 28 foreach (WebPermissions.WebModulePermission perm in WebPermissions.Instance.GetModules ()) { 29 if (!first) { 30 writer.WriteValueSeparator (); 31 } 13 32 14 JsonArray perms = new JsonArray (); 15 foreach (WebPermissions.WebModulePermission perm in WebPermissions.Instance.GetModules ()) { 16 JsonObject permObj = new JsonObject (); 17 permObj.Add ("module", new JsonString (perm.module)); 18 permObj.Add ("allowed", new JsonBoolean (perm.permissionLevel >= _context.PermissionLevel)); 19 perms.Add (permObj); 33 first = false; 34 35 writer.WriteRaw (jsonModuleKey); 36 writer.WriteString (perm.module); 37 38 writer.WriteRaw (jsonAllowedKey); 39 writer.WriteBoolean (perm.permissionLevel >= _context.PermissionLevel); 40 41 writer.WriteEndObject (); 20 42 } 21 43 22 result.Add ("permissions", perms); 23 24 WebUtils.WriteJson (_context.Response, result); 44 writer.WriteEndArray (); 45 46 writer.WriteEndObject (); 47 48 WebUtils.SendEnvelopedResult (_context, ref writer); 25 49 } 26 50 } -
binary-improvements2/WebServer/src/Web.cs
r398 r402 3 3 using System.IO; 4 4 using System.Net.Sockets; 5 using AllocsFixes.FileCache;6 using MapRendering;7 5 using SpaceWizards.HttpListener; 8 6 using UnityEngine; 7 using Webserver.FileCache; 9 8 using Webserver.UrlHandlers; 10 9 using Cookie = System.Net.Cookie; … … 14 13 namespace Webserver { 15 14 public class Web : IConsoleServer { 15 public static event Action<Web> ServerInitialized; 16 16 17 private const int guestPermissionLevel = 2000; 17 18 private const string indexPageUrl = "/app"; … … 26 27 public Web (string _modInstancePath) { 27 28 try { 28 int webPort = GamePrefs.GetInt (EnumUtils.Parse<EnumGamePrefs> ( "ControlPanelPort"));29 int webPort = GamePrefs.GetInt (EnumUtils.Parse<EnumGamePrefs> (nameof (EnumGamePrefs.ControlPanelPort))); 29 30 if (webPort < 1 || webPort > 65533) { 30 31 Log.Out ("[Web] Webserver not started (ControlPanelPort not within 1-65533)"); … … 44 45 45 46 string webfilesFolder = DetectWebserverFolder (_modInstancePath); 46 string webfilesFolderLegacy = _modInstancePath + "/weblegacy";47 string webfilesFolderLegacy = $"{_modInstancePath}/weblegacy"; 47 48 48 49 connectionHandler = new ConnectionHandler (); … … 56 57 RegisterPathHandler ("/weblegacy", new StaticHandler ( 57 58 webfilesFolderLegacy, 58 useStaticCache ? (AbstractCache)new SimpleCache () : new DirectAccess (),59 useStaticCache ? new SimpleCache () : new DirectAccess (), 59 60 false) 60 61 ); … … 68 69 RegisterPathHandler ("/files/", new StaticHandler ( 69 70 webfilesFolder, 70 useStaticCache ? (AbstractCache)new SimpleCache () : new DirectAccess (),71 useStaticCache ? new SimpleCache () : new DirectAccess (), 71 72 false) 72 73 ); 73 74 RegisterPathHandler ("/itemicons/", new ItemIconHandler (true)); 74 RegisterPathHandler ("/map/", new StaticHandler (75 GameIO.GetSaveGameDir () + "/map",76 MapRenderer.GetTileCache (),77 false,78 "web.map")79 );80 75 RegisterPathHandler ("/api/", new ApiHandler ()); 76 77 // Allow other code to add their stuff 78 ServerInitialized?.Invoke (this); 81 79 82 80 listener.Prefixes.Add ($"http://+:{webPort}/"); … … 87 85 SdtdConsole.Instance.RegisterServer (this); 88 86 89 Log.Out ( "[Web] Started Webserver on port " + webPort);87 Log.Out ($"[Web] Started Webserver on port {webPort}"); 90 88 } catch (Exception e) { 91 89 Log.Error ("[Web] Error in Web.ctor: "); … … 95 93 96 94 private static string DetectWebserverFolder (string _modInstancePath) { 97 string webserverFolder = _modInstancePath + "/webserver";95 string webserverFolder = $"{_modInstancePath}/webserver"; 98 96 99 97 foreach (Mod mod in ModManager.GetLoadedMods ()) { 100 string modServerFolder = mod.Path + "/webserver";98 string modServerFolder = $"{mod.Path}/webserver"; 101 99 102 100 if (Directory.Exists (modServerFolder)) { … … 127 125 foreach (Mod mod in ModManager.GetLoadedMods ()) { 128 126 try { 129 string webModPath = mod.Path + "/WebMod";127 string webModPath = $"{mod.Path}/WebMod"; 130 128 if (!Directory.Exists (webModPath)) { 131 129 continue; … … 136 134 webMods.Add (webMod); 137 135 } catch (InvalidDataException e) { 138 Log.Error ($"[Web] Could not load webmod from mod {mod. ModInfo.Name.Value}: {e.Message}");136 Log.Error ($"[Web] Could not load webmod from mod {mod.Name}: {e.Message}"); 139 137 } 140 138 } catch (Exception e) { 141 Log.Error ( "[Web] Failed loading web mods from mod " + mod.ModInfo.Name.Value);139 Log.Error ($"[Web] Failed loading web mods from mod {mod.Name}"); 142 140 Log.Exception (e); 143 141 } … … 150 148 listener.Close (); 151 149 } catch (Exception e) { 152 Log.Out ( "[Web] Error in Web.Disconnect: " + e);150 Log.Out ($"[Web] Error in Web.Disconnect: {e}"); 153 151 } 154 152 } … … 238 236 } catch (IOException e) { 239 237 if (e.InnerException is SocketException) { 240 Log.Out ( "[Web] Error in Web.HandleRequest(): Remote host closed connection: " + e.InnerException.Message);238 Log.Out ($"[Web] Error in Web.HandleRequest(): Remote host closed connection: {e.InnerException.Message}"); 241 239 } else { 242 Log.Out ( "[Web] Error (IO) in Web.HandleRequest(): " + e);240 Log.Out ($"[Web] Error (IO) in Web.HandleRequest(): {e}"); 243 241 } 244 242 } catch (Exception e) { … … 313 311 } 314 312 315 Log.Warning ( "[Web] Invalid Admintoken used from " + reqRemoteEndPoint);313 Log.Warning ($"[Web] Invalid Admintoken used from {reqRemoteEndPoint}"); 316 314 317 315 return guestPermissionLevel; -
binary-improvements2/WebServer/src/WebAPI/APIs/Animal.cs
r401 r402 1 1 using System.Collections.Generic; 2 using AllocsFixes.JSON;3 using AllocsFixes.LiveData;4 2 using JetBrains.Annotations; 3 using Utf8Json; 4 using Webserver.LiveData; 5 5 6 namespace Webserver.WebAPI {6 namespace Webserver.WebAPI.APIs { 7 7 [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> (); 10 10 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"); 13 14 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); 18 38 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 (); 31 40 } 32 33 pJson.Add ("position", jsonPOS);34 35 animalsJsResult.Add (pJson);36 41 } 37 38 WebUtils.WriteJson (_context.Response, animalsJsResult); 42 43 writer.WriteEndArray (); 44 SendEnvelopedResult (_context, ref writer); 39 45 } 40 46 } -
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 1 1 using System.Collections.Generic; 2 using AllocsFixes.JSON;3 using AllocsFixes.LiveData;4 2 using JetBrains.Annotations; 3 using Utf8Json; 4 using Webserver.LiveData; 5 5 6 namespace Webserver.WebAPI {6 namespace Webserver.WebAPI.APIs { 7 7 [UsedImplicitly] 8 internal class GetHostileLocation : AbsWebAPI{9 private readonly List<EntityEnemy> en emies = new List<EntityEnemy> ();8 internal class Hostile : AbsRestApi { 9 private readonly List<EntityEnemy> entities = new List<EntityEnemy> (); 10 10 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"); 13 14 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); 18 38 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 (); 31 40 } 32 33 pJson.Add ("position", jsonPOS);34 35 hostilesJsResult.Add (pJson);36 41 } 37 38 WebUtils.WriteJson (_context.Response, hostilesJsResult); 42 43 writer.WriteEndArray (); 44 SendEnvelopedResult (_context, ref writer); 39 45 } 40 46 } -
binary-improvements2/WebServer/src/WebAPI/APIs/Log.cs
r401 r402 1 1 using System.Collections.Generic; 2 using AllocsFixes.JSON;3 2 using JetBrains.Annotations; 3 using Utf8Json; 4 4 5 namespace Webserver.WebAPI {5 namespace Webserver.WebAPI.APIs { 6 6 [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"); 9 19 10 p ublic override void HandleRequest (RequestContext _context) {20 protected override void HandleRestGet (RequestContext _context) { 11 21 if (_context.Request.QueryString ["count"] == null || !int.TryParse (_context.Request.QueryString ["count"], out int count)) { 12 22 count = 50; … … 17 27 } 18 28 19 if (count > MAX_COUNT) {20 count = MAX_COUNT;29 if (count > maxCount) { 30 count = maxCount; 21 31 } 22 32 23 if (count < - MAX_COUNT) {24 count = - MAX_COUNT;33 if (count < -maxCount) { 34 count = -maxCount; 25 35 } 26 36 … … 28 38 firstLine = count > 0 ? LogBuffer.Instance.OldestLine : LogBuffer.Instance.LatestLine; 29 39 } 30 31 JsonObject result = new JsonObject (); 32 40 41 PrepareEnvelopedResult (out JsonWriter writer); 42 43 writer.WriteRaw (jsonKeyEntries); 44 33 45 List<LogBuffer.LogEntry> logEntries = LogBuffer.Instance.GetRange (ref firstLine, count, out int lastLine); 34 46 35 JsonArray entries = new JsonArray (); 47 writer.WriteBeginArray (); 48 49 bool first = true; 36 50 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 (); 44 73 } 74 writer.WriteEndArray (); 45 75 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 (); 49 83 50 WebUtils.WriteJson (_context.Response, result);84 SendEnvelopedResult (_context, ref writer); 51 85 } 52 86 } -
binary-improvements2/WebServer/src/WebAPI/APIs/ServerInfo.cs
r401 r402 1 using System;2 using AllocsFixes.JSON;3 1 using JetBrains.Annotations; 2 using Utf8Json; 4 3 5 namespace Webserver.WebAPI {4 namespace Webserver.WebAPI.APIs { 6 5 [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"); 10 8 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 11 22 GameServerInfo gsi = ConnectionManager.Instance.LocalServerInfo; 12 23 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 15 27 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); 19 30 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 (); 21 47 } 22 48 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); 25 51 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 } 29 55 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 (); 31 68 } 32 69 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); 35 72 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 } 39 76 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 (); 41 89 } 90 91 writer.WriteEndObject (); 92 93 buildSampler.End (); 42 94 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); 45 101 } 46 102 } -
binary-improvements2/WebServer/src/WebAPI/APIs/ServerStats.cs
r401 r402 1 using AllocsFixes.JSON;2 using AllocsFixes.LiveData;3 1 using JetBrains.Annotations; 2 using Utf8Json; 3 using Webserver.LiveData; 4 4 5 namespace Webserver.WebAPI {5 namespace Webserver.WebAPI.APIs { 6 6 [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"); 10 16 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); 16 21 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 (); 20 34 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); 22 47 } 23 48 -
binary-improvements2/WebServer/src/WebAPI/APIs/WebMods.cs
r401 r402 1 using AllocsFixes.JSON;2 1 using JetBrains.Annotations; 2 using Utf8Json; 3 3 4 namespace Webserver.WebAPI {4 namespace Webserver.WebAPI.APIs { 5 5 [UsedImplicitly] 6 public class GetWebMods : AbsWebAPI{7 private readonly JsonArray loadedWebMods = new JsonArray ();6 public class WebMods : AbsRestApi { 7 private readonly byte[] loadedWebMods; 8 8 9 public GetWebMods (Web _parent) { 9 public WebMods (Web _parent) { 10 JsonWriter writer = new JsonWriter (); 11 writer.WriteBeginArray (); 12 13 bool first = true; 10 14 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); 12 25 13 modJson.Add ("name", new JsonString (webMod.ParentMod.ModInfo.Name.Value));14 15 26 string webModReactBundle = webMod.ReactBundle; 16 27 if (webModReactBundle != null) { 17 modJson.Add ("bundle", new JsonString (webModReactBundle)); 28 writer.WriteValueSeparator (); 29 writer.WriteString ("bundle"); 30 writer.WriteNameSeparator (); 31 writer.WriteString (webModReactBundle); 18 32 } 19 33 20 34 string webModCssFile = webMod.CssPath; 21 35 if (webModCssFile != null) { 22 modJson.Add ("css", new JsonString (webModCssFile)); 36 writer.WriteValueSeparator (); 37 writer.WriteString ("css"); 38 writer.WriteNameSeparator (); 39 writer.WriteString (webModCssFile); 23 40 } 41 42 writer.WriteEndObject (); 43 } 44 45 writer.WriteEndArray (); 24 46 25 loadedWebMods.Add (modJson); 26 } 47 loadedWebMods = writer.ToUtf8ByteArray (); 27 48 } 28 49 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); 31 54 } 32 55 -
binary-improvements2/WebServer/src/WebAPI/APIs/WebUiUpdates.cs
r401 r402 1 using AllocsFixes.JSON;2 using AllocsFixes.LiveData;3 1 using JetBrains.Annotations; 2 using Utf8Json; 3 using Webserver.LiveData; 4 4 5 namespace Webserver.WebAPI {5 namespace Webserver.WebAPI.APIs { 6 6 [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) { 9 20 if (_context.Request.QueryString ["latestLine"] == null || 10 21 !int.TryParse (_context.Request.QueryString ["latestLine"], out int latestLine)) { 11 22 latestLine = 0; 12 23 } 24 25 PrepareEnvelopedResult (out JsonWriter writer); 26 27 writer.WriteRaw (jsonKeyGameTime); 13 28 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 (); 15 41 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); 21 53 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 (); 25 55 26 result.Add ("newlogs", new JsonNumber (LogBuffer.Instance.LatestLine - latestLine)); 27 28 WebUtils.WriteJson (_context.Response, result); 56 SendEnvelopedResult (_context, ref writer); 29 57 } 30 58 -
binary-improvements2/WebServer/src/WebAPI/AbsRestApi.cs
r394 r402 1 1 using System; 2 using System.Collections.Generic; 2 3 using System.IO; 3 4 using System.Net; 4 using AllocsFixes.JSON;5 using Utf8Json; 5 6 6 7 namespace Webserver.WebAPI { … … 9 10 10 11 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 (); 12 33 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; 27 36 } 28 37 } … … 31 40 switch (_context.Request.HttpMethod) { 32 41 case "GET": 33 if ( jsonBody!= null) {34 SendE nvelopedResult (_context, null, HttpStatusCode.BadRequest, jsonBody, "GET_WITH_BODY");42 if (inputJson != null) { 43 SendErrorResult (_context, HttpStatusCode.BadRequest, jsonInputData, "GET_WITH_BODY"); 35 44 return; 36 45 } … … 40 49 case "POST": 41 50 if (!string.IsNullOrEmpty (_context.RequestPath)) { 42 SendE nvelopedResult (_context, null, HttpStatusCode.BadRequest, jsonBody, "POST_WITH_ID");51 SendErrorResult (_context, HttpStatusCode.BadRequest, jsonInputData, "POST_WITH_ID"); 43 52 return; 44 53 } 45 54 46 if ( jsonBody== null) {47 SendE nvelopedResult (_context, null, HttpStatusCode.BadRequest, null, "POST_WITHOUT_BODY");55 if (inputJson == null) { 56 SendErrorResult (_context, HttpStatusCode.BadRequest, null, "POST_WITHOUT_BODY"); 48 57 return; 49 58 } 50 59 51 HandleRestPost (_context, jsonBody);60 HandleRestPost (_context, inputJson, jsonInputData); 52 61 return; 53 62 case "PUT": 54 63 if (string.IsNullOrEmpty (_context.RequestPath)) { 55 SendE nvelopedResult (_context, null, HttpStatusCode.BadRequest, jsonBody, "PUT_WITHOUT_ID");64 SendErrorResult (_context, HttpStatusCode.BadRequest, jsonInputData, "PUT_WITHOUT_ID"); 56 65 return; 57 66 } 58 67 59 if ( jsonBody== null) {60 SendE nvelopedResult (_context, null, HttpStatusCode.BadRequest, null, "PUT_WITHOUT_BODY");68 if (inputJson == null) { 69 SendErrorResult (_context, HttpStatusCode.BadRequest, null, "PUT_WITHOUT_BODY"); 61 70 return; 62 71 } 63 72 64 HandleRestPut (_context, jsonBody);73 HandleRestPut (_context, inputJson, jsonInputData); 65 74 return; 66 75 case "DELETE": 67 76 if (string.IsNullOrEmpty (_context.RequestPath)) { 68 SendE nvelopedResult (_context, null, HttpStatusCode.BadRequest, jsonBody, "DELETE_WITHOUT_ID");77 SendErrorResult (_context, HttpStatusCode.BadRequest, jsonInputData, "DELETE_WITHOUT_ID"); 69 78 return; 70 79 } 71 80 72 if ( jsonBody!= null) {73 SendE nvelopedResult (_context, null, HttpStatusCode.BadRequest, null, "DELETE_WITH_BODY");81 if (inputJson != null) { 82 SendErrorResult (_context, HttpStatusCode.BadRequest, null, "DELETE_WITH_BODY"); 74 83 return; 75 84 } … … 78 87 return; 79 88 default: 80 SendE nvelopedResult (_context, null, HttpStatusCode.BadRequest, null, "INVALID_METHOD");89 SendErrorResult (_context, HttpStatusCode.BadRequest, null, "INVALID_METHOD"); 81 90 return; 82 91 } 83 92 } catch (Exception e) { 84 SendE nvelopedResult (_context, null, HttpStatusCode.InternalServerError, jsonBody, "ERROR_PROCESSING", e);93 SendErrorResult (_context, HttpStatusCode.InternalServerError, jsonInputData, "ERROR_PROCESSING", e); 85 94 } 86 95 } 87 96 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); 111 101 } 112 102 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) { 114 123 _value = default; 115 124 116 if (!_jsonObject.TryGetValue (_fieldName, out JsonNodefieldNode)) {125 if (!_jsonObject.TryGetValue (_fieldName, out object fieldNode)) { 117 126 return false; 118 127 } 119 128 120 if ( !(fieldNode is JsonValue valueField)) {129 if (fieldNode is not double value) { 121 130 return false; 122 131 } 123 132 124 133 try { 125 _value = valueField.AsInt;134 _value = (int)value; 126 135 return true; 127 136 } catch (Exception) { … … 130 139 } 131 140 132 protected bool TryGetJsonField ( JsonObject_jsonObject, string _fieldName, out double _value) {141 protected bool TryGetJsonField (IDictionary<string, object> _jsonObject, string _fieldName, out double _value) { 133 142 _value = default; 134 143 135 if (!_jsonObject.TryGetValue (_fieldName, out JsonNodefieldNode)) {144 if (!_jsonObject.TryGetValue (_fieldName, out object fieldNode)) { 136 145 return false; 137 146 } 138 147 139 if ( !(fieldNode is JsonValue valueField)) {148 if (fieldNode is not double value) { 140 149 return false; 141 150 } 142 151 143 152 try { 144 _value = value Field.AsDouble;153 _value = value; 145 154 return true; 146 155 } catch (Exception) { … … 149 158 } 150 159 151 protected bool TryGetJsonField ( JsonObject_jsonObject, string _fieldName, out string _value) {160 protected bool TryGetJsonField (IDictionary<string, object> _jsonObject, string _fieldName, out string _value) { 152 161 _value = default; 153 162 154 if (!_jsonObject.TryGetValue (_fieldName, out JsonNodefieldNode)) {163 if (!_jsonObject.TryGetValue (_fieldName, out object fieldNode)) { 155 164 return false; 156 165 } 157 166 158 if ( !(fieldNode is JsonValue valueField)) {167 if (fieldNode is not string value) { 159 168 return false; 160 169 } 161 170 162 171 try { 163 _value = value Field.AsString;172 _value = value; 164 173 return true; 165 174 } catch (Exception) { … … 168 177 } 169 178 170 protected abstract void HandleRestGet (RequestContext _context); 179 protected virtual void HandleRestGet (RequestContext _context) { 180 SendErrorResult (_context, HttpStatusCode.MethodNotAllowed, null, "Unsupported"); 181 } 171 182 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 } 173 186 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 } 175 190 176 protected abstract void HandleRestDelete (RequestContext _context); 191 protected virtual void HandleRestDelete (RequestContext _context) { 192 SendErrorResult (_context, HttpStatusCode.MethodNotAllowed, null, "Unsupported"); 193 } 177 194 } 178 195 } -
binary-improvements2/WebServer/src/WebCommandResult.cs
r399 r402 4 4 using System.Net.Sockets; 5 5 using System.Text; 6 using AllocsFixes.JSON;7 6 using UnityEngine; 8 using HttpListenerResponse = SpaceWizards.HttpListener.HttpListenerResponse;7 using Utf8Json; 9 8 10 9 namespace Webserver { … … 19 18 private readonly string parameters; 20 19 21 private readonly HttpListenerResponse response;20 private readonly RequestContext context; 22 21 private readonly ResultType responseType; 23 22 24 public WebCommandResult (string _command, string _parameters, ResultType _responseType, HttpListenerResponse _response) {25 response = _response;23 public WebCommandResult (string _command, string _parameters, ResultType _responseType, RequestContext _context) { 24 context = _context; 26 25 command = _command; 27 26 parameters = _parameters; … … 29 28 } 30 29 30 private static readonly byte[] jsonRawKey = JsonWriter.GetEncodedPropertyNameWithBeginObject ("resultRaw"); 31 32 private static readonly byte[] jsonCommandKey = JsonWriter.GetEncodedPropertyNameWithBeginObject ("command"); 33 private static readonly byte[] jsonParametersKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("parameters"); 34 private static readonly byte[] jsonResultKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("result"); 35 31 36 public void SendLines (List<string> _output) { 32 37 StringBuilder sb = new StringBuilder (); … … 35 40 } 36 41 42 string commandOutput = sb.ToString (); 43 37 44 try { 38 response.SendChunked = false;39 40 45 if (responseType == ResultType.Raw) { 41 WebUtils.WriteText ( response, sb.ToString ());46 WebUtils.WriteText (context.Response, commandOutput); 42 47 } else { 43 JsonNode result; 48 WebUtils.PrepareEnvelopedResult (out JsonWriter writer); 49 44 50 if (responseType == ResultType.ResultOnly) { 45 result = new JsonString (sb.ToString ()); 51 writer.WriteRaw (jsonRawKey); 52 writer.WriteString (commandOutput); 53 writer.WriteEndObject (); 46 54 } else { 47 JsonObject resultObj = new JsonObject (); 48 49 resultObj.Add ("command", new JsonString (command)); 50 resultObj.Add ("parameters", new JsonString (parameters)); 51 resultObj.Add ("result", new JsonString (sb.ToString ())); 52 53 result = resultObj; 55 writer.WriteRaw (jsonCommandKey); 56 writer.WriteString (command); 57 58 writer.WriteRaw (jsonParametersKey); 59 writer.WriteString (parameters); 60 61 writer.WriteRaw (jsonResultKey); 62 writer.WriteString (commandOutput); 63 64 writer.WriteEndObject (); 54 65 } 55 66 56 WebUtils. WriteJson (response, result);67 WebUtils.SendEnvelopedResult (context, ref writer); 57 68 } 58 69 } catch (IOException e) { 59 70 if (e.InnerException is SocketException) { 60 Log.Warning ( "[Web] Error in WebCommandResult.SendLines(): Remote host closed connection: " + e.InnerException.Message);71 Log.Warning ($"[Web] Error in WebCommandResult.SendLines(): Remote host closed connection: {e.InnerException.Message}"); 61 72 } else { 62 Log.Warning ( "[Web] Error (IO) in WebCommandResult.SendLines(): " + e);73 Log.Warning ($"[Web] Error (IO) in WebCommandResult.SendLines(): {e}"); 63 74 } 64 75 } catch (Exception e) { 65 Log.Warning ( "[Web] Error in WebCommandResult.SendLines(): " + e);76 Log.Warning ($"[Web] Error in WebCommandResult.SendLines(): {e}"); 66 77 } finally { 67 response?.Close ();78 context?.Response?.Close (); 68 79 } 69 80 } … … 82 93 83 94 public string GetDescription () { 84 return "WebCommandResult_for_" + command;95 return $"WebCommandResult_for_{command}"; 85 96 } 86 97 } -
binary-improvements2/WebServer/src/WebConnection.cs
r391 r402 25 25 login = DateTime.Now; 26 26 lastAction = login; 27 conDescription = "WebPanel from " + Endpoint;27 conDescription = $"WebPanel from {Endpoint}"; 28 28 } 29 29 -
binary-improvements2/WebServer/src/WebMod.cs
r391 r402 1 1 using System.IO; 2 using AllocsFixes.FileCache;2 using Webserver.FileCache; 3 3 using Webserver.UrlHandlers; 4 4 … … 14 14 15 15 public WebMod (Web _parentWeb, Mod _parentMod, bool _useStaticCache) { 16 string folder = _parentMod.Path + "/WebMod";16 string folder = $"{_parentMod.Path}/WebMod"; 17 17 if (!Directory.Exists (folder)) { 18 18 throw new InvalidDataException("No WebMod folder in mod"); … … 21 21 string urlWebModBase = $"{modsBaseUrl}{_parentMod.FolderName}/"; 22 22 23 ReactBundle = folder + "/" + reactBundleName; 24 if (File.Exists (ReactBundle)) { 25 ReactBundle = urlWebModBase + reactBundleName; 26 } else { 27 ReactBundle = null; 28 } 23 ReactBundle = $"{folder}/{reactBundleName}"; 24 ReactBundle = File.Exists (ReactBundle) ? $"{urlWebModBase}{reactBundleName}" : null; 29 25 30 CssPath = folder + "/" + stylingFileName; 31 if (File.Exists (CssPath)) { 32 CssPath = urlWebModBase + stylingFileName; 33 } else { 34 CssPath = null; 35 } 26 CssPath = $"{folder}/{stylingFileName}"; 27 CssPath = File.Exists (CssPath) ? $"{urlWebModBase}{stylingFileName}" : null; 36 28 37 29 if (ReactBundle == null && CssPath == null) { … … 43 35 _parentWeb.RegisterPathHandler (urlWebModBase, new StaticHandler ( 44 36 folder, 45 _useStaticCache ? (AbstractCache)new SimpleCache () : new DirectAccess (),37 _useStaticCache ? new SimpleCache () : new DirectAccess (), 46 38 false) 47 39 ); -
binary-improvements2/WebServer/src/WebPermissions.cs
r399 r402 36 36 private readonly ReadOnlyCollection<WebModulePermission> allModulesListRo; 37 37 38 private static string SettingsFilePath => GamePrefs.GetString (EnumUtils.Parse<EnumGamePrefs> ( "SaveGameFolder"));38 private static string SettingsFilePath => GamePrefs.GetString (EnumUtils.Parse<EnumGamePrefs> (nameof (EnumGamePrefs.SaveGameFolder))); 39 39 private static string SettingsFileName => permissionsFileName; 40 private static string SettingsFullPath => SettingsFilePath + "/" + SettingsFileName;40 private static string SettingsFullPath => $"{SettingsFilePath}/{SettingsFileName}"; 41 41 42 42 private WebPermissions () { … … 184 184 185 185 private void OnFileChanged (object _source, FileSystemEventArgs _e) { 186 Log.Out ( "[Web] [Perms] Reloading " + SettingsFileName);186 Log.Out ($"[Web] [Perms] Reloading {SettingsFileName}"); 187 187 Load (); 188 188 } … … 205 205 xmlDoc.Load (SettingsFullPath); 206 206 } catch (XmlException e) { 207 Log.Error ( "[Web] [Perms] Failed loading permissions file: " + e.Message);207 Log.Error ($"[Web] [Perms] Failed loading permissions file: {e.Message}"); 208 208 return; 209 209 } -
binary-improvements2/WebServer/src/WebUtils.cs
r394 r402 1 1 using System; 2 using System.Diagnostics.CodeAnalysis; 2 3 using System.Net; 3 4 using System.Text; 4 using AllocsFixes.JSON;5 using Utf8Json; 5 6 using HttpListenerRequest = SpaceWizards.HttpListener.HttpListenerRequest; 6 7 using HttpListenerResponse = SpaceWizards.HttpListener.HttpListenerResponse; … … 8 9 namespace Webserver { 9 10 public static class WebUtils { 11 // ReSharper disable once MemberCanBePrivate.Global 10 12 public const string MimePlain = "text/plain"; 11 13 public const string MimeHtml = "text/html"; 14 // ReSharper disable once MemberCanBePrivate.Global 12 15 public const string MimeJson = "application/json"; 13 16 14 private static readonly UnityEngine.Profiling.CustomSampler jsonSerializeSampler = UnityEngine.Profiling.CustomSampler.Create ("JSON_Serialize");17 private static readonly UnityEngine.Profiling.CustomSampler envelopeBuildSampler = UnityEngine.Profiling.CustomSampler.Create ("JSON_EnvelopeBuilding"); 15 18 private static readonly UnityEngine.Profiling.CustomSampler netWriteSampler = UnityEngine.Profiling.CustomSampler.Create ("JSON_Write"); 16 17 public static void WriteJson (HttpListenerResponse _resp, JsonNode _root, HttpStatusCode _statusCode = HttpStatusCode.OK) {18 jsonSerializeSampler.Begin ();19 StringBuilder sb = new StringBuilder ();20 _root.ToString (sb);21 jsonSerializeSampler.End ();22 netWriteSampler.Begin ();23 WriteText (_resp, sb.ToString(), _statusCode, MimeJson);24 netWriteSampler.End ();25 }26 19 27 20 public static void WriteText (HttpListenerResponse _resp, string _text, HttpStatusCode _statusCode = HttpStatusCode.OK, string _mimeType = null) { … … 43 36 return Guid.NewGuid ().ToString (); 44 37 } 38 39 [SuppressMessage ("ReSharper", "MemberCanBePrivate.Global")] 40 public static void WriteJsonData (HttpListenerResponse _resp, ref JsonWriter _jsonWriter, HttpStatusCode _statusCode = HttpStatusCode.OK) { 41 ArraySegment<byte> jsonData = _jsonWriter.GetBuffer (); 42 43 netWriteSampler.Begin (); 44 _resp.StatusCode = (int)_statusCode; 45 _resp.ContentType = MimeJson; 46 _resp.ContentEncoding = Encoding.UTF8; 47 _resp.ContentLength64 = jsonData.Count; 48 _resp.OutputStream.Write (jsonData.Array!, 0, jsonData.Count); 49 netWriteSampler.End (); 50 } 51 52 53 private static readonly byte[] jsonRawDataKey = JsonWriter.GetEncodedPropertyNameWithBeginObject ("data"); // {"data": 54 55 private static readonly byte[] jsonRawMetaKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("meta"); // ,"meta": 56 private static readonly byte[] jsonRawMetaServertimeKey = JsonWriter.GetEncodedPropertyNameWithBeginObject ("serverTime"); // {"serverTime": 57 private static readonly byte[] jsonRawMetaRequestMethodKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("requestMethod"); // ,"requestMethod": 58 private static readonly byte[] jsonRawMetaRequestSubpathKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("requestSubpath"); // ,"requestSubpath": 59 private static readonly byte[] jsonRawMetaRequestBodyKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("requestBody"); // ,"requestBody": 60 private static readonly byte[] jsonRawMetaErrorCodeKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("errorCode"); // ,"errorCode": 61 private static readonly byte[] jsonRawMetaExceptionMessageKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("exceptionMessage"); // ,"exceptionMessage": 62 private static readonly byte[] jsonRawMetaExceptionTraceKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("exceptionTrace"); // ,"exceptionTrace": 63 64 public static void PrepareEnvelopedResult (out JsonWriter _writer) { 65 _writer = new JsonWriter (); 66 _writer.WriteRaw (jsonRawDataKey); 67 } 68 69 public static void SendEnvelopedResult (RequestContext _context, ref JsonWriter _writer, HttpStatusCode _statusCode = HttpStatusCode.OK, 70 byte[] _jsonInputData = null, string _errorCode = null, Exception _exception = null) { 71 72 envelopeBuildSampler.Begin (); 73 74 _writer.WriteRaw (jsonRawMetaKey); 75 76 _writer.WriteRaw (jsonRawMetaServertimeKey); 77 _writer.WriteString (DateTime.Now.ToString ("o")); 78 79 if (!string.IsNullOrEmpty (_errorCode)) { 80 _writer.WriteRaw (jsonRawMetaRequestMethodKey); 81 _writer.WriteString (_context.Request.HttpMethod); 82 83 _writer.WriteRaw (jsonRawMetaRequestSubpathKey); 84 _writer.WriteString (_context.RequestPath); 85 86 _writer.WriteRaw (jsonRawMetaRequestBodyKey); 87 if (_jsonInputData != null) { 88 _writer.WriteRaw (_jsonInputData); 89 } else { 90 _writer.WriteNull (); 91 } 92 93 _writer.WriteRaw (jsonRawMetaErrorCodeKey); 94 _writer.WriteString (_errorCode); 95 96 if (_exception != null) { 97 _writer.WriteRaw (jsonRawMetaExceptionMessageKey); 98 _writer.WriteString (_exception.Message); 99 100 _writer.WriteRaw (jsonRawMetaExceptionTraceKey); 101 _writer.WriteString (_exception.StackTrace); 102 } 103 } 104 105 _writer.WriteEndObject (); // End of "meta" object 106 _writer.WriteEndObject (); // End of overall result object 107 108 envelopeBuildSampler.End (); 109 110 WriteJsonData (_context.Response, ref _writer, _statusCode); 111 } 45 112 } 46 113 }
Note:
See TracChangeset
for help on using the changeset viewer.