Skip to content

Commit 2f4236d

Browse files
authored
Merge pull request #17 from project-fika/dev-1.0.3
Dev > main
2 parents 72ef355 + a520b2f commit 2f4236d

File tree

11 files changed

+391
-205
lines changed

11 files changed

+391
-205
lines changed

FikaServer/API/GetStatisticsController.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ public IActionResult HandleRequest()
4242
BodyDamage = (player.CharacterData?.PmcData?.Stats?.Eft?.OverallCounters?.Items?
4343
.Where(x => x.Key?.Count == 1 && x.Key.Contains("CauseBodyDamage"))
4444
.Select(x => x.Value)
45-
.FirstOrDefault() ?? 0.0),
45+
.FirstOrDefault() / 100f ?? 0.0),
4646
ArmorDamage = (player.CharacterData?.PmcData?.Stats?.Eft?.OverallCounters?.Items?
4747
.Where(x => x.Key?.Count == 1 && x.Key.Contains("CauseArmorDamage"))
4848
.Select(x => x.Value)
49-
.FirstOrDefault() ?? 0.0),
49+
.FirstOrDefault() / 100f ?? 0.0),
5050
Headshots = (player.CharacterData?.PmcData?.Stats?.Eft?.OverallCounters?.Items?
5151
.Where(x => x.Key?.Count == 1 && x.Key.Contains("HeadShots"))
5252
.Select(x => x.Value)

FikaServer/API/PlayersController.cs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using FikaServer.Models;
2+
using FikaServer.Models.Enums;
3+
using FikaServer.Models.Fika.Presence;
24
using FikaServer.Services;
35
using FikaServer.Services.Cache;
46
using FikaShared;
@@ -13,8 +15,26 @@ namespace FikaServer.API;
1315
[ApiController]
1416
[Route("fika/api/players")]
1517
[RequireApiKey]
16-
public class PlayersController(FikaProfileService profileService, SaveServer saveServer, PresenceService presenceService) : ControllerBase
18+
public class PlayersController(FikaProfileService profileService, SaveServer saveServer, PresenceService presenceService,
19+
ILogger<PlayersController> logger) : ControllerBase
1720
{
21+
private static readonly Dictionary<string, EFikaLocation> _locationMap = new(StringComparer.OrdinalIgnoreCase)
22+
{
23+
["bigmap"] = EFikaLocation.Customs,
24+
["factory4_day"] = EFikaLocation.Factory,
25+
["factory4_night"] = EFikaLocation.Factory,
26+
["interchange"] = EFikaLocation.Interchange,
27+
["laboratory"] = EFikaLocation.Laboratory,
28+
["labyrinth"] = EFikaLocation.Labyrinth,
29+
["lighthouse"] = EFikaLocation.Lighthouse,
30+
["rezervbase"] = EFikaLocation.Reserve,
31+
["sandbox"] = EFikaLocation.GroundZero,
32+
["sandbox_high"] = EFikaLocation.GroundZero,
33+
["shoreline"] = EFikaLocation.Shoreline,
34+
["tarkovstreets"] = EFikaLocation.Streets,
35+
["woods"] = EFikaLocation.Woods
36+
};
37+
1838
[HttpGet]
1939
public IActionResult HandleRequest()
2040
{
@@ -40,10 +60,11 @@ public IActionResult HandleRequest()
4060
EFikaLocation location;
4161
if (presence != null)
4262
{
43-
location = presence.ToFikaLocation();
63+
location = ToFikaLocation(presence);
4464
}
4565
else
4666
{
67+
logger.LogWarning("Present was null when trying to fetch info for {Nickname}", profile.CharacterData?.PmcData?.Info?.Nickname ?? profileId);
4768
location = EFikaLocation.None;
4869
}
4970

@@ -63,4 +84,25 @@ public IActionResult HandleRequest()
6384

6485
return Ok(playersResponse);
6586
}
87+
88+
private EFikaLocation ToFikaLocation(FikaPlayerPresence presence)
89+
{
90+
if (presence.RaidInformation != null)
91+
{
92+
if (_locationMap.TryGetValue(presence.RaidInformation.Location, out var eLocation))
93+
{
94+
return eLocation;
95+
}
96+
97+
logger.LogWarning("Location was incorrect when getting presense for {Nickname}", presence.Nickname);
98+
return EFikaLocation.None;
99+
}
100+
101+
if (presence.Activity is EFikaPlayerPresences.IN_HIDEOUT)
102+
{
103+
return EFikaLocation.Hideout;
104+
}
105+
106+
return EFikaLocation.None;
107+
}
66108
}

FikaServer/Controllers/RaidController.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ public async Task<FikaRaidCreateResponse> HandleRaidCreate(FikaRaidCreateRequest
4141
hostUsername = headlessHelper.GetHeadlessNickname(request.ServerId);
4242
}
4343

44-
var requesterName = headlessHelper.GetRequesterUsername(request.ServerId) ?? hostUsername;
44+
var requesterName = headlessHelper.GetRequesterUsername(request.ServerId)
45+
?? hostUsername;
4546

4647
await notificationWebSocket.BroadcastAsync(new StartRaidNotification
4748
{
@@ -52,7 +53,7 @@ await notificationWebSocket.BroadcastAsync(new StartRaidNotification
5253
RaidTime = request.Time
5354
});
5455

55-
await webhookService.SendWebhookMessage($"{requesterName} has started a raid on {request.Settings.Location.ToLower().ToFikaLocation()}.");
56+
await webhookService.SendWebhookMessage($"{requesterName} has started a {request.Side} raid on {request.Settings.Location.ToLower().ToFikaLocation()}.");
5657

5758
return new FikaRaidCreateResponse
5859
{

FikaServer/ExtensionMethods.cs

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -83,35 +83,6 @@ public static EFikaLocation ToFikaLocation(this string location)
8383
};
8484
}
8585

86-
public static EFikaLocation ToFikaLocation(this FikaPlayerPresence presence)
87-
{
88-
if (presence.RaidInformation != null)
89-
{
90-
return presence.RaidInformation.Location switch
91-
{
92-
"bigmap" => EFikaLocation.Customs,
93-
"factory4_day" or "factory4_night" => EFikaLocation.Factory,
94-
"interchange" => EFikaLocation.Interchange,
95-
"laboratory" => EFikaLocation.Laboratory,
96-
"labyrinth" => EFikaLocation.Labyrinth,
97-
"lighthouse" => EFikaLocation.Lighthouse,
98-
"rezervbase" => EFikaLocation.Reserve,
99-
"sandbox" or "sandbox_high" => EFikaLocation.GroundZero,
100-
"shoreline" => EFikaLocation.Shoreline,
101-
"tarkovstreets" => EFikaLocation.Streets,
102-
"woods" => EFikaLocation.Woods,
103-
_ => EFikaLocation.None,
104-
};
105-
}
106-
107-
if (presence.Activity is EFikaPlayerPresences.IN_HIDEOUT)
108-
{
109-
return EFikaLocation.Hideout;
110-
}
111-
112-
return EFikaLocation.None;
113-
}
114-
11586
/// <summary>
11687
/// Checks if the given profile is a headless profile
11788
/// </summary>

FikaServer/FikaModMetadata.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ public record FikaModMetadata : AbstractModMetadata, IModWebMetadata
1414
public override bool? IsBundleMod { get; init; } = false;
1515
public override string License { get; init; } = "CC-BY-NC-SA-4.0";
1616
public override string ModGuid { get; init; } = "Fika";
17-
public override SemanticVersioning.Version Version { get; init; } = new(1, 0, 2);
17+
public override SemanticVersioning.Version Version { get; init; } = new(1, 0, 3);
1818
public override SemanticVersioning.Range SptVersion { get; init; } = new("~4.0.0");
1919
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace FikaServer.Models.Servers;
2+
3+
public enum NatIntroductionType
4+
{
5+
Server,
6+
Client
7+
}
8+
9+
public class NatIntroductionRequest(NatIntroductionType natIntroductionType, string sessionId)
10+
{
11+
public NatIntroductionType Type { get; } = natIntroductionType;
12+
public string SessionId { get; } = sessionId;
13+
}

FikaServer/Models/Servers/NatPunchServerPeer.cs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,10 @@
22

33
namespace FikaServer.Models.Servers;
44

5-
public class NatPunchServerPeer
5+
public class NatPunchServerPeer(string sessionId, IPEndPoint internalAddr, IPEndPoint externalAddr)
66
{
7-
public IPEndPoint InternalAddr { get; }
8-
public IPEndPoint ExternalAddr { get; }
9-
public DateTime CreationTime { get; }
10-
11-
public NatPunchServerPeer(IPEndPoint internalAddr, IPEndPoint externalAddr)
12-
{
13-
InternalAddr = internalAddr;
14-
ExternalAddr = externalAddr;
15-
CreationTime = DateTime.UtcNow;
16-
}
7+
public string SessionId { get; set; } = sessionId;
8+
public IPEndPoint InternalAddr { get; } = internalAddr;
9+
public IPEndPoint ExternalAddr { get; } = externalAddr;
10+
public DateTime LastKeepAliveTime { get; set; } = DateTime.UtcNow;
1711
}

FikaServer/Servers/NatPunchServer.cs

Lines changed: 81 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66
using System.Collections.Generic;
77
using System.Net;
88
using System.Net.Sockets;
9+
using static Fika.Core.Networking.LiteNetLib.EventBasedNatPunchListener;
910

1011
namespace FikaServer.Servers;
1112

1213
[Injectable(InjectionType.Singleton)]
1314
public class NatPunchServer(ConfigService fikaConfig, ISptLogger<NatPunchServer> logger) : INatPunchListener, INetEventListener
1415
{
15-
private readonly Dictionary<string, NatPunchServerPeer> _natPunchServerPeers = [];
16+
private readonly List<NatPunchServerPeer> _serverPeers = [];
1617
private NetManager? _netServer;
1718
private CancellationTokenSource? _pollEventsRoutineCts;
1819

@@ -51,67 +52,71 @@ public void Stop()
5152

5253
public void PollEvents()
5354
{
54-
_netServer?.PollEvents();
5555
_netServer?.NatPunchModule.PollEvents();
5656
}
5757

5858
public void OnNatIntroductionRequest(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, string token)
5959
{
60-
string introductionType;
61-
string sessionId;
60+
DateTime dateTimeNow = DateTime.UtcNow;
61+
62+
NatIntroductionRequest? natIntroductionRequest;
6263

6364
try
6465
{
65-
introductionType = token.Split(':')[0];
66-
sessionId = token.Split(':')[1];
66+
natIntroductionRequest = GetNatIntroductionRequestFromToken(token);
6767
}
68-
catch (Exception ex)
68+
catch
6969
{
70-
logger.Error($"[Fika NatPunch] Error when parsing NatIntroductionRequest: {ex.Message}");
70+
Console.WriteLine($"[Fika NatPunch] Error when parsing token: {token}");
7171
return;
7272
}
7373

74-
switch (introductionType)
74+
if (natIntroductionRequest == null)
7575
{
76-
case "server":
77-
if (_natPunchServerPeers.ContainsKey(sessionId))
78-
{
79-
logger.Info($"[Fika NatPunch] KeepAlive {sessionId} ({remoteEndPoint})");
80-
}
81-
else
82-
{
83-
logger.Info($"[Fika NatPunch] Added {sessionId} ({remoteEndPoint}) to server list");
84-
}
76+
Console.WriteLine($"[Fika NatPunch] Malformed Nat Introduction Request sent by client: {remoteEndPoint}. Token: {token}");
77+
return;
78+
}
8579

86-
_natPunchServerPeers[sessionId] = new(localEndPoint, remoteEndPoint);
87-
break;
80+
NatPunchServerPeer? serverPeer = _serverPeers.FirstOrDefault(peer => peer.SessionId == natIntroductionRequest.SessionId);
8881

89-
case "client":
90-
if (_natPunchServerPeers.TryGetValue(sessionId, out NatPunchServerPeer? sPeer))
91-
{
92-
logger.Info($"[Fika NatPunch] Introducing server {sessionId} ({sPeer.ExternalAddr}) to client ({remoteEndPoint})");
93-
94-
for (int i = 0; i < fikaConfig.Config.NatPunchServer.NatIntroduceAmount; i++)
95-
{
96-
_netServer?.NatPunchModule.NatIntroduce(
97-
sPeer.InternalAddr,
98-
sPeer.ExternalAddr,
99-
localEndPoint,
100-
remoteEndPoint,
101-
token
102-
);
103-
}
104-
}
105-
else
106-
{
107-
logger.Info($"[Fika NatPunch] Unknown ServerId provided by client.");
108-
}
109-
break;
82+
if (natIntroductionRequest.Type == NatIntroductionType.Server)
83+
{
84+
if (serverPeer != null)
85+
{
86+
serverPeer.LastKeepAliveTime = dateTimeNow;
11087

111-
default:
112-
logger.Info($"[Fika NatPunch] Unknown request received: {token}");
113-
break;
88+
Console.WriteLine($"[Fika NatPunch] KeepAlive {natIntroductionRequest.SessionId} ({remoteEndPoint})");
89+
}
90+
else
91+
{
92+
serverPeer = new(natIntroductionRequest.SessionId, localEndPoint, remoteEndPoint);
93+
_serverPeers.Add(serverPeer);
11494

95+
Console.WriteLine($"[Fika NatPunch] Added {serverPeer.SessionId} ({serverPeer.ExternalAddr}) to server list");
96+
}
97+
}
98+
99+
if (natIntroductionRequest.Type == NatIntroductionType.Client)
100+
{
101+
if (serverPeer != null)
102+
{
103+
Console.WriteLine($"[Fika NatPunch] Introducing server {serverPeer.SessionId} ({serverPeer.ExternalAddr}) to client ({remoteEndPoint})");
104+
105+
for (int i = 0; i < fikaConfig.Config.NatPunchServer.NatIntroduceAmount; i++)
106+
{
107+
_netServer?.NatPunchModule.NatIntroduce(
108+
serverPeer.InternalAddr,
109+
serverPeer.ExternalAddr,
110+
localEndPoint,
111+
remoteEndPoint,
112+
token
113+
);
114+
}
115+
}
116+
else
117+
{
118+
Console.WriteLine($"Unknown sessionId ({natIntroductionRequest.SessionId}) provided by client: {remoteEndPoint}");
119+
}
115120
}
116121
}
117122

@@ -160,23 +165,11 @@ public void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo)
160165
// Do nothing
161166
}
162167

163-
private void RemoveInactiveServerPeers()
168+
private void RemoteInactivePeers()
164169
{
165170
DateTime dateTimeNow = DateTime.UtcNow;
166171

167-
foreach (string sessionId in _natPunchServerPeers.Keys)
168-
{
169-
NatPunchServerPeer peer = _natPunchServerPeers[sessionId];
170-
171-
if (peer != null)
172-
{
173-
if (dateTimeNow - peer.CreationTime > TimeSpan.FromMinutes(1))
174-
{
175-
_natPunchServerPeers.Remove(sessionId);
176-
logger.Info($"[Fika NatPunch] Removed inactive server: {sessionId} ({peer.ExternalAddr})");
177-
}
178-
}
179-
}
172+
_serverPeers.RemoveAll(peer => dateTimeNow - peer.LastKeepAliveTime > TimeSpan.FromMinutes(1));
180173
}
181174

182175
private async Task PollEventsRoutine()
@@ -189,9 +182,37 @@ private async Task PollEventsRoutine()
189182
}
190183

191184
PollEvents();
192-
RemoveInactiveServerPeers();
185+
RemoteInactivePeers();
193186

194-
await Task.Delay(TimeSpan.FromSeconds(1));
187+
await Task.Delay(TimeSpan.FromMilliseconds(500));
195188
}
196189
}
190+
191+
private NatIntroductionRequest? GetNatIntroductionRequestFromToken(string token)
192+
{
193+
if (!token.Contains(':'))
194+
{
195+
return null;
196+
}
197+
198+
string introductionType = token.Split(':')[0];
199+
string sessionId = token.Split(':')[1];
200+
201+
if (introductionType != "Client" && introductionType != "Server")
202+
{
203+
return null;
204+
}
205+
206+
if (sessionId.Length != 24)
207+
{
208+
return null;
209+
}
210+
211+
if (Enum.TryParse(introductionType, out NatIntroductionType natIntroductionType))
212+
{
213+
return new(natIntroductionType, sessionId);
214+
}
215+
216+
return null;
217+
}
197218
}

0 commit comments

Comments
 (0)