Skip to content

Commit 41c9739

Browse files
author
Matthew Bate
committed
Update PlayerName encoding for the API to protect special characters in names and chat messages. Allowed for non-base64 strings for API compatibility. Will remove in Version 2.0.
1 parent a74c599 commit 41c9739

File tree

4 files changed

+82
-18
lines changed

4 files changed

+82
-18
lines changed

BHD-ServerManager/API/Controllers/ChatController.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using HawkSyncShared.DTOs;
33
using Microsoft.AspNetCore.Authorization;
44
using Microsoft.AspNetCore.Mvc;
5+
using HawkSyncShared.SupportClasses;
56

67
[ApiController]
78
[Route("api/[controller]")]
@@ -12,9 +13,12 @@ public class ChatController : ControllerBase
1213
public ActionResult<CommandResult> SendMessage([FromBody] SendChatCommand command)
1314
{
1415
if (!HasPermission("chat")) return Forbid();
16+
1517
if (command.Channel < 0 || command.Channel > 3)
1618
return BadRequest(new CommandResult { Success = false, Message = "Invalid channel." });
1719

20+
string chatMessage = Func.FB64(command.Message);
21+
1822
var result = chatInstanceManager.SendChatMessage(command.Message, command.Channel);
1923
return Ok(new CommandResult { Success = result.Success, Message = result.Message });
2024
}

BHD-ServerManager/API/Controllers/PlayerController.cs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using HawkSyncShared.DTOs;
55
using System.Net;
66
using HawkSyncShared;
7+
using HawkSyncShared.SupportClasses;
78

89
namespace BHD_ServerManager.API.Controllers;
910

@@ -18,7 +19,9 @@ public ActionResult<CommandResult> ArmPlayer([FromBody] ArmPlayerCommand command
1819
{
1920
if(!HasPermission("players")) return Forbid();
2021

21-
var result = playerInstanceManager.ArmPlayer(command.PlayerSlot, command.PlayerName);
22+
string playerName = Func.FB64(command.PlayerName);
23+
24+
var result = playerInstanceManager.ArmPlayer(command.PlayerSlot, playerName);
2225

2326
return Ok(new CommandResult
2427
{
@@ -31,7 +34,9 @@ public ActionResult<CommandResult> DisarmPlayer([FromBody] DisarmPlayerCommand c
3134
{
3235
if(!HasPermission("players")) return Forbid();
3336

34-
var result = playerInstanceManager.DisarmPlayer(command.PlayerSlot, command.PlayerName);
37+
string playerName = Func.FB64(command.PlayerName);
38+
39+
var result = playerInstanceManager.DisarmPlayer(command.PlayerSlot, playerName);
3540

3641
return Ok(new CommandResult
3742
{
@@ -47,7 +52,9 @@ public ActionResult<CommandResult> ToggleGodMode([FromBody] GodModePlayerCommand
4752

4853
bool IsGod = CommonCore.instancePlayers!.PlayerList[command.PlayerSlot].IsGod;
4954

50-
var result = playerInstanceManager.ToggleGodMode(command.PlayerSlot, command.PlayerName, !IsGod);
55+
string playerName = Func.FB64(command.PlayerName);
56+
57+
var result = playerInstanceManager.ToggleGodMode(command.PlayerSlot, playerName, !IsGod);
5158

5259
return Ok(new CommandResult
5360
{
@@ -60,7 +67,9 @@ public ActionResult<CommandResult> SwitchTeamPlayer([FromBody] SwitchTeamPlayerC
6067
{
6168
if(!HasPermission("players")) return Forbid();
6269

63-
var result = playerInstanceManager.SwitchPlayerTeam(command.PlayerSlot, command.PlayerName, command.TeamNum);
70+
string playerName = Func.FB64(command.PlayerName);
71+
72+
var result = playerInstanceManager.SwitchPlayerTeam(command.PlayerSlot, playerName, command.TeamNum);
6473

6574
return Ok(new CommandResult
6675
{
@@ -73,8 +82,8 @@ public ActionResult<CommandResult> SwitchTeamPlayer([FromBody] SwitchTeamPlayerC
7382
public ActionResult<CommandResult> KickPlayer([FromBody] KickPlayerCommand command)
7483
{
7584
if(!HasPermission("players")) return Forbid();
76-
77-
var result = playerInstanceManager.KickPlayer(command.PlayerSlot, command.PlayerName);
85+
var PlayerName = Func.FB64(command.PlayerName);
86+
var result = playerInstanceManager.KickPlayer(command.PlayerSlot, PlayerName);
7887

7988
return Ok(new CommandResult
8089
{
@@ -88,7 +97,7 @@ public async Task<ActionResult<CommandResult>> BanPlayer([FromBody] BanPlayerCom
8897
{
8998
if(!HasPermission("players")) return Forbid();
9099

91-
string playerName = command.PlayerName;
100+
string playerName = Func.FB64(command.PlayerName);
92101
string playerIP = command.PlayerIP;
93102
int playerSlot = command.PlayerSlot;
94103
bool banIP = command.BanIP;
@@ -163,9 +172,11 @@ public ActionResult<CommandResult> WarnPlayer([FromBody] WarnPlayerCommand comma
163172
{
164173
if(!HasPermission("players")) return Forbid();
165174

175+
string playerName = Func.FB64(command.PlayerName);
176+
166177
var result = playerInstanceManager.WarnPlayer(
167178
command.PlayerSlot,
168-
command.PlayerName,
179+
playerName,
169180
command.Message);
170181

171182
return Ok(new CommandResult
@@ -180,7 +191,9 @@ public ActionResult<CommandResult> KillPlayer([FromBody] KillPlayerCommand comma
180191
{
181192
if(!HasPermission("players")) return Forbid();
182193

183-
var result = playerInstanceManager.KillPlayer(command.PlayerSlot, command.PlayerName);
194+
string playerName = Func.FB64(command.PlayerName);
195+
196+
var result = playerInstanceManager.KillPlayer(command.PlayerSlot, playerName);
184197

185198
return Ok(new CommandResult
186199
{
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace HawkSyncShared.SupportClasses
6+
{
7+
public static class Func
8+
{
9+
private const string Base64Marker = "__B64__";
10+
11+
public static string TB64(string input)
12+
{
13+
if (input == null) return string.Empty;
14+
var bytes = Encoding.GetEncoding(1252).GetBytes(input);
15+
return Base64Marker + Convert.ToBase64String(bytes);
16+
}
17+
18+
public static string FB64(string input)
19+
{
20+
if (input == null) return string.Empty;
21+
if (input.StartsWith(Base64Marker))
22+
{
23+
var base64Part = input.Substring(Base64Marker.Length);
24+
var bytes = Convert.FromBase64String(base64Part);
25+
return Encoding.GetEncoding(1252).GetString(bytes);
26+
}
27+
// Not marked as Base64, return as-is
28+
return input;
29+
}
30+
31+
public static bool IsMarkedBase64(string input)
32+
{
33+
return input != null && input.StartsWith(Base64Marker);
34+
}
35+
}
36+
}

RemoteClient/Services/ApiClient.cs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using HawkSyncShared.DTOs;
2+
using HawkSyncShared.SupportClasses;
23
using System.Net.Http.Headers;
34
using System.Net.Http.Json;
5+
using System.Security.Cryptography;
46
using System.Threading.Channels;
57
using System.Windows.Forms;
68

@@ -107,47 +109,55 @@ public async Task<LoginResponse> LoginAsync(string username, string password)
107109

108110
public async Task<CommandResult> KickPlayerAsync(int playerSlot, string playerName)
109111
{
110-
var command = new KickPlayerCommand(playerSlot, playerName);
112+
var PlayerName = Func.TB64(playerName);
113+
var command = new KickPlayerCommand(playerSlot, PlayerName);
111114
return await SendCommandAsync("/api/player/kick", command);
112115
}
113116

114117
public async Task<CommandResult> BanPlayerAsync(int playerSlot, string playerName, string playerIP, bool banIP)
115118
{
116-
var command = new BanPlayerCommand(playerSlot, playerName, playerIP, banIP);
119+
var PlayerName = Func.TB64(playerName);
120+
var command = new BanPlayerCommand(playerSlot, PlayerName, playerIP, banIP);
117121
return await SendCommandAsync("/api/player/ban", command);
118122
}
119123

120124
public async Task<CommandResult> WarnPlayerAsync(int playerSlot, string playerName, string message)
121125
{
122-
var command = new WarnPlayerCommand(playerSlot, playerName, message);
126+
var PlayerName = Func.TB64(playerName);
127+
var command = new WarnPlayerCommand(playerSlot, PlayerName, message);
123128
return await SendCommandAsync("/api/player/warn", command);
124129
}
125130

126131
public async Task<CommandResult> KillPlayerAsync(int playerSlot, string playerName)
127132
{
128-
var command = new KillPlayerCommand(playerSlot, playerName);
133+
var PlayerName = Func.TB64(playerName);
134+
var command = new KillPlayerCommand(playerSlot, PlayerName);
129135
return await SendCommandAsync("/api/player/kill", command);
130136
}
131137

132138
public async Task<CommandResult> ArmPlayerAsync(int playerSlot, string playerName)
133139
{
134-
var command = new ArmPlayerCommand(playerSlot, playerName);
140+
var PlayerName = Func.TB64(playerName);
141+
var command = new ArmPlayerCommand(playerSlot, PlayerName);
135142
return await SendCommandAsync("/api/player/arm", command);
136143
}
137144

138145
public async Task<CommandResult> DisarmPlayerAsync(int playerSlot, string playerName)
139146
{
140-
var command = new DisarmPlayerCommand(playerSlot, playerName);
147+
var PlayerName = Func.TB64(playerName);
148+
var command = new DisarmPlayerCommand(playerSlot, PlayerName);
141149
return await SendCommandAsync("/api/player/disarm", command);
142150
}
143151
public async Task<CommandResult> ToggleGodPlayerAsync(int playerSlot, string playerName)
144152
{
145-
var command = new GodModePlayerCommand(playerSlot, playerName);
153+
var PlayerName = Func.TB64(playerName);
154+
var command = new GodModePlayerCommand(playerSlot, PlayerName);
146155
return await SendCommandAsync("/api/player/togglegodmode", command);
147156
}
148157
public async Task<CommandResult> SwitchTeamPlayerAsync(int playerSlot, string playerName, int teamNum)
149158
{
150-
var command = new SwitchTeamPlayerCommand(playerSlot, playerName, teamNum);
159+
var PlayerName = Func.TB64(playerName);
160+
var command = new SwitchTeamPlayerCommand(playerSlot, PlayerName, teamNum);
151161
return await SendCommandAsync("/api/player/switchteam", command);
152162
}
153163

@@ -157,7 +167,8 @@ public async Task<CommandResult> SwitchTeamPlayerAsync(int playerSlot, string pl
157167

158168
public async Task<CommandResult> SendChatAsync(string message, int channel = 1)
159169
{
160-
var command = new SendChatCommand(message, channel);
170+
var Message = Func.TB64(message);
171+
var command = new SendChatCommand(Message, channel);
161172
return await SendCommandAsync("/api/chat/send", command);
162173
}
163174

0 commit comments

Comments
 (0)