Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge grpc to continue work from master #43

Merged
merged 86 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
e6e5a89
grpc wip
Xsear Jan 4, 2024
27f93dc
update proto
Xsear Jan 5, 2024
3c5b5ca
Fix usings
Xsear Jan 6, 2024
3889960
Add SDB Base
Xsear Jan 13, 2024
9e818dc
Update proto
Xsear Jan 18, 2024
e33daf3
aptitude wip
Xsear Jan 21, 2024
1ed2bcf
Use remote frame id with base warpaint
Xsear Jan 27, 2024
4cd8ca4
Further work on Aptitude, Deployables
Xsear Jan 29, 2024
91a83a3
Terminal interactions
Xsear Feb 3, 2024
9b1f93b
Delete unused old packets
Xsear Feb 3, 2024
9d7aaf4
Use AeroMessages for Control channel so that the remaining old packet…
Xsear Feb 3, 2024
264f0ab
Melding and Outpost
Xsear Feb 3, 2024
187b575
Vehicle
Xsear Feb 4, 2024
bd40042
Fix entity ids
Xsear Feb 4, 2024
fdcd9f0
Minor cleanup
Xsear Feb 4, 2024
38a06e2
Avoid spawning ents on time 0
Xsear Feb 9, 2024
9b1f162
Fix glider params command
Xsear Feb 9, 2024
f2b1c5e
Remove character on logout
Xsear Feb 9, 2024
d45844e
Big brain strat to avoid socket errors
Xsear Feb 9, 2024
a37d3ba
Copy customdb to output so it loads when not run from source
Xsear Feb 9, 2024
82b6308
Fix null check when changing controller props
Xsear Feb 10, 2024
e66ad3a
Load Monster into Character
Xsear Feb 10, 2024
72eb4ae
Loadout hack
Xsear Feb 10, 2024
5b5f0a2
Add some stats
Xsear Feb 10, 2024
7141048
Support rollback effect
Xsear Feb 11, 2024
74beff7
Add remove effect params for Meteor Strike
Xsear Feb 11, 2024
4aebec8
Add RequireCStateCommand
Xsear Feb 11, 2024
c1fdfff
Execute apply chain before considering effect applied
Xsear Feb 11, 2024
6d83181
Move AbilityActivated out of Apt to ensure we send it before the effects
Xsear Feb 11, 2024
1bf656b
Force flush on effect changes
Xsear Feb 11, 2024
6b28709
Revert "Execute apply chain before considering effect applied"
Xsear Feb 11, 2024
b4b74c7
Add RequireWeaponArmed and RequirementServer
Xsear Feb 15, 2024
7279e14
Load weapon attributes
Xsear Feb 15, 2024
3d35e9a
Testing charge
Xsear Feb 15, 2024
8d9bd38
Temp workaround for hidden effect
Xsear Feb 15, 2024
81f9134
Add thumper
Xsear Feb 15, 2024
861b4c2
Add carryable
Xsear Feb 15, 2024
c012897
Default deployable health to 0 for now
Xsear Feb 15, 2024
1255b84
Work on register, stat modifier
Xsear Feb 17, 2024
59431cb
Handle incomming split messages without checking seqnum
Xsear Feb 17, 2024
1fbbe4d
Bugfix no targets with ApplyEffect and AuthTerminal
Xsear Feb 17, 2024
edcec08
Force shard creation on startup to give ents time to spawn
Xsear Feb 17, 2024
87ca855
Adjust split handling
Xsear Feb 17, 2024
7b5cc19
Load more deployables
Xsear Feb 17, 2024
1d7beae
Cleanup
Xsear Feb 17, 2024
86e3f98
Scoping by distance, KeyframeRequest, Checksum
Xsear Feb 23, 2024
682b33d
Grpc in separate class
Xsear Feb 23, 2024
acd720e
Zone chat
Xsear Feb 23, 2024
9c9f622
Server commands
Xsear Feb 23, 2024
4dc7d61
Update AeroMessages
Xsear Feb 24, 2024
4d081ac
Spectate experiment
Xsear Feb 25, 2024
b9cb1a7
Remove unused IInstance
Xsear Feb 25, 2024
8366384
Work on inventory, calldowns
Xsear Feb 26, 2024
44e5637
Dont send to disconnected players
Xsear Feb 26, 2024
00ccf86
Cleanup
Xsear Feb 26, 2024
4814966
Further work on inventory and loadouts
Xsear Mar 2, 2024
c8ac7b4
Set thumper to global scope
Xsear Mar 2, 2024
8c8fcdc
Add SzymonKaminski's ReloadArmyServerCommand
Xsear Mar 2, 2024
f241ba7
Add some debug commands
Xsear Mar 2, 2024
3917fbf
Update AeroMessages
Xsear Mar 2, 2024
3507e05
Expose position to apt
Xsear Mar 3, 2024
5880e84
Add deployable spawn
Xsear Mar 3, 2024
3c08f3b
Add TargetInitiatorCommand
Xsear Mar 3, 2024
755b6d9
Update AeroMessages
Xsear Mar 4, 2024
edbc843
Cleanup
Xsear Mar 4, 2024
d03555a
Handle events from Grpc stream (#38)
SzymonKaminski Mar 11, 2024
9c96d22
Map vehicle component types to sdb_guids (#39)
SzymonKaminski Mar 17, 2024
2786f60
Aero.Gen -> 1.2.15
Xsear Mar 17, 2024
cbdbb14
Update AeroMessages
Xsear Mar 17, 2024
aa395c1
Remove GitHub Actions build for .NET 6 & 7
eXpl0it3r Mar 17, 2024
8ddbae3
Update README.md
Xsear Mar 17, 2024
9a709e4
Cleanup warnings
Xsear Mar 17, 2024
874dfa9
Save session data on logout, add spawn points (#40)
SzymonKaminski Mar 28, 2024
67c344c
Update AeroMessages and Aero.Gen
Xsear Mar 28, 2024
6cdcc50
Fix Apt stack check
Xsear Mar 29, 2024
6b7225a
Fix admin unk command output
Xsear Mar 29, 2024
e0cbc29
Log force movement cancel id
Xsear Mar 29, 2024
f1e73fe
Admin combat flags
Xsear Mar 29, 2024
40ab874
Fixup configuration
Xsear Apr 30, 2024
ff31727
Update AeroMessages
Xsear May 1, 2024
8e8ade1
FauFau -> 1.3.0
Xsear May 1, 2024
8525e3a
Fix SDBLoader backup index
Xsear May 1, 2024
57227f5
Basic Inventory Management (#41)
Vicegale May 3, 2024
be10d49
Update format of Aptitude console logs (#42)
SzymonKaminski May 3, 2024
ae27b78
Update AeroMessages
Xsear May 3, 2024
efcb552
Update .bat paths
Xsear May 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 0 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ jobs:
- { name: Windows VS2022, os: windows-2022 }
- { name: macOS, os: macos-13 }
dotnet:
- { name: .NET 6, version: "6.0.x" }
- { name: .NET 7, version: "7.0.x" }
- { name: .NET 8, version: "8.0.x" }

steps:
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -368,4 +368,7 @@ MigrationBackup/
.ionide/

# Fody - auto-generated XML schema
FodyWeavers.xsd
FodyWeavers.xsd

# VSCode Shared Configuration Files
.vscode/
2 changes: 1 addition & 1 deletion Lib/AeroMessages
Submodule AeroMessages updated 27 files
+1 −1 AeroMessages/AeroMessages.csproj
+2 −0 AeroMessages/Common/HalfValueTypes.cs
+12 −1 AeroMessages/Common/QuantisedValues.cs
+5 −3 AeroMessages/GSS/V66/AreaVisualData/View/MapMarkerView.cs
+32 −1 AeroMessages/GSS/V66/Character/CharacterShared.cs
+1 −1 AeroMessages/GSS/V66/Character/Command/BuyBackPreviousDay.cs
+1 −1 AeroMessages/GSS/V66/Character/Command/ClaimDailyRewardStreak.cs
+10 −7 AeroMessages/GSS/V66/Character/Command/MovementInput.cs
+16 −14 AeroMessages/GSS/V66/Character/Command/MovementInputFake.cs
+11 −11 AeroMessages/GSS/V66/Character/Command/SendMailToPlayer.cs
+9 −1 AeroMessages/GSS/V66/Character/Command/TimedDailyRewardRequest.cs
+12 −8 AeroMessages/GSS/V66/Character/Command/UiQueryResponse.cs
+12 −5 AeroMessages/GSS/V66/Character/Controller/BaseController.cs
+5 −3 AeroMessages/GSS/V66/Character/Controller/MissionAndMarkerController.cs
+19 −18 AeroMessages/GSS/V66/Character/Event/DailyLoginRewardsUpdateEvt.cs
+0 −14 AeroMessages/GSS/V66/Character/Event/DisplayRewards.cs
+2 −2 AeroMessages/GSS/V66/Character/Event/InventoryUpdate.cs
+17 −8 AeroMessages/GSS/V66/Character/Event/NewUiQuery.cs
+6 −18 AeroMessages/GSS/V66/Character/Event/SimulateLootPickup.cs
+2 −4 AeroMessages/GSS/V66/Character/Event/UiQueryCancelled.cs
+12 −2 AeroMessages/GSS/V66/Generic/Event/DisplayUiNotification.cs
+11 −2 AeroMessages/GSS/V66/Generic/Event/PingMap.cs
+2 −2 AeroMessages/GSS/V66/Generic/Event/PingMapMarker.cs
+1 −1 AeroMessages/GSS/V66/Generic/Event/ScoreBoardUpdatePlayerStatus.cs
+20 −8 AeroMessages/GSS/V66/Generic/Event/SendTipMessage.cs
+111 −13 AeroMessages/GSS/V66/Shared.cs
+2 −2 AeroMessages/GSS/V66/Vehicle/Command/ReceiveCollisionDamage.cs
2 changes: 1 addition & 1 deletion Lib/Shared.Udp/Serializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public static Memory<byte> WriteStruct<T>(T packet)
var size = Unsafe.SizeOf<T>();
Memory<byte> memory = new byte[size];

MemoryMarshal.Write(memory.Span, ref packet);
MemoryMarshal.Write(memory.Span, in packet);

return memory;
}
Expand Down
3 changes: 2 additions & 1 deletion Lib/Shared.Web/BaseWebServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public static IHost Build(Type serverType, IConfiguration configuration)
}

Log.Information($"Starting web host {serverType.FullName}");
#pragma warning disable SYSLIB0039 // TLS 1.0 required
var hostBuilder =
Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(webBuilder =>
Expand Down Expand Up @@ -71,7 +72,7 @@ public static IHost Build(Type serverType, IConfiguration configuration)
});
})
.UseSerilog();

#pragma warning restore SYSLIB0039
return hostBuilder.Build();
}
catch (Exception ex)
Expand Down
2 changes: 2 additions & 0 deletions PIN.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,13 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UGSS/@EntryIndexedValue">UGSS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ABRT/@EntryIndexedValue">ABRT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=LocalConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=a4f433b8_002Dabcd_002D4e55_002Da08f_002D82e78cef0f0c/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Local constants"&gt;&lt;ElementKinds&gt;&lt;Kind Name="LOCAL_CONSTANT" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAlwaysTreatStructAsNotReorderableMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Baneclaw/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Battlelab/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Cinerarium/@EntryIndexedValue">True</s:Boolean>
Expand Down
2 changes: 1 addition & 1 deletion PIN.targets
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>latest</LangVersion>
<CodeAnalysisRuleSet>..\..\stylecop.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
Expand Down
29 changes: 13 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ https://user-images.githubusercontent.com/920861/134824107-03e9f99c-b420-47c7-b7
4. Download the [latest PIN release](https://github.com/themeldingwars/PIN/releases/latest)
5. Make a backup copy of the original `FirefallClient.exe` in `Firefall\system\bin`
6. Replace the `FirefallClient.exe` with the patched `FirefallClient.exe` from the PIN release
7. Make sure the [.NET 6 Runtime](https://dotnet.microsoft.com/download/dotnet/6.0) is installed
7. Make sure the [.NET 8 Runtime](https://dotnet.microsoft.com/download/dotnet/8.0) is installed
8. Trust self-signed development certificates by running `dotnet dev-certs https --trust`
9. Start all three applications:
- GameServer
Expand Down Expand Up @@ -44,29 +44,26 @@ PlayIntroMovie = false

### Features

- Loading into any of the existing zone
- Basic character movement, including jetpacks
- Primary and secondary weapon usage
- **Note:** In about one third of the cases, the weapons can't be used, try a relog in those cases
- One partially working ability that breaks the camera position
- Sound effects, ambient and music
- The map can be opened
- Loading into any zone (WebHostManager)
- Basic character movement, including jetpacks and gliders
- Switch between battleframes with preconfigured loadouts
- Customize character appearance in NewYou (RIN.WebAPI)
- Call down vehicles and some deployables

### Limitations

- Weapons don't always work
- Jetpacks are missing all visual effects
- There is no combat, projectile or damage simulation
- Most of the UI doesn't work properly
- No gliders
- No abilities
- No call downs
- No NPCs of any sort
- No Melding
- Most abilities are not fully working
- Vehicles only have physics if a player is driving it (client-side)
- No AI
- No Encounters
- No PvP

## Development

1. Install Visual Studio or JetBrains Rider
- Include the [.NET 6 SDK](https://dotnet.microsoft.com/download/dotnet/6.0) component or install it separately
- Include the [.NET 8 SDK](https://dotnet.microsoft.com/download/dotnet/8.0) component or install it separately
2. Recursive clone the repository `git clone --recurse-submodules https://github.com/themeldingwars/PIN.git`
3. Build the solution
4. Trust self-signed development certificates by running `dotnet dev-certs https --trust`
Expand Down
2 changes: 1 addition & 1 deletion StartGameServer.bat
Original file line number Diff line number Diff line change
@@ -1 +1 @@
start /D UdpHosts\GameServer\bin\Debug\net6.0 UdpHosts\GameServer\bin\Debug\net6.0\GameServer.exe
start /D UdpHosts\GameServer\bin\Debug\net8.0 UdpHosts\GameServer\bin\Debug\net8.0\GameServer.exe
2 changes: 1 addition & 1 deletion StartMatrixServer.bat
Original file line number Diff line number Diff line change
@@ -1 +1 @@
start /D UdpHosts\MatrixServer\bin\Debug\net6.0 UdpHosts\MatrixServer\bin\Debug\net6.0\MatrixServer.exe
start /D UdpHosts\MatrixServer\bin\Debug\net8.0 UdpHosts\MatrixServer\bin\Debug\net8.0\MatrixServer.exe
2 changes: 1 addition & 1 deletion StartWebHostManager.bat
Original file line number Diff line number Diff line change
@@ -1 +1 @@
start /D WebHostManager\bin\Debug\net6.0 WebHostManager\bin\Debug\net6.0\WebHostManager.exe
start /D WebHostManager\bin\Debug\net8.0 WebHostManager\bin\Debug\net8.0\WebHostManager.exe
4 changes: 3 additions & 1 deletion UdpHosts/GameServer/App.Default.config
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<configuration>
<appSettings>
<add key="serilog:minimum-level" value="Debug"/>
<!-- More settings here -->
<add key="Port" value="25001"/>
<add key="GrpcChannelAddress" value="http://localhost:5201"/>
<add key="StaticDBPath" value="C:\Program Files\Steam\steamapps\common\Firefall\system\db\clientdb.sd2"/>
</appSettings>
</configuration>
118 changes: 99 additions & 19 deletions UdpHosts/GameServer/Channel.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#nullable enable
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
Expand Down Expand Up @@ -29,6 +31,7 @@ public class Channel
private readonly INetworkClient _client;
private readonly ConcurrentQueue<GamePacket> _incomingPackets;
private readonly ConcurrentQueue<Memory<byte>> _outgoingPackets;
private SortedDictionary<ushort, GamePacket> _incomingSplitMessagePackets;

private Channel(ChannelType channelType, bool isSequenced, bool isReliable, INetworkClient networkClient, ILogger logger)
{
Expand All @@ -42,6 +45,7 @@ private Channel(ChannelType channelType, bool isSequenced, bool isReliable, INet

_incomingPackets = new ConcurrentQueue<GamePacket>();
_outgoingPackets = new ConcurrentQueue<Memory<byte>>();
_incomingSplitMessagePackets = new SortedDictionary<ushort, GamePacket>();
}

public delegate void PacketAvailableDelegate(GamePacket packet);
Expand All @@ -54,6 +58,7 @@ private Channel(ChannelType channelType, bool isSequenced, bool isReliable, INet
private ushort CurrentSequenceNumber { get; set; }
private DateTime LastActivity { get; set; }
private ushort LastAck { get; set; }
private bool InSplitMode { get; set; }

public static Dictionary<ChannelType, Channel> GetChannels(INetworkClient client, ILogger logger)
{
Expand Down Expand Up @@ -90,6 +95,7 @@ public void Process(CancellationToken ct)
}

// TODO: Implement SequencedPacketQueue
// TODO: Fix resent message handling
if (packet.Header.ResendCount > 0)
{
// de-xor data
Expand Down Expand Up @@ -126,18 +132,45 @@ public void Process(CancellationToken ct)
_logger.Fatal("---> Resent packet!!! C:{0}: {1} bytes", Type, packet.TotalBytes);
}

if (packet.Header.IsSplit)
// TODO: Ensure we follow sequence number when combining split messages
if (InSplitMode)
{
_logger.Fatal("---> Split packet!!! C:{0}: {1} bytes", Type, packet.TotalBytes);
}
_incomingSplitMessagePackets.Add(sequenceNumber, packet);
if (!packet.Header.IsSplit)
{
// Finish split mode
InSplitMode = false;
var combined = _incomingSplitMessagePackets
.SelectMany((pair) => pair.Value.PacketData[2..].ToArray()) // Skip seqnum
.ToArray();
_incomingSplitMessagePackets.Clear();

var combinedPacket = new GamePacket(packet.Header, new ReadOnlyMemory<byte>(combined));

if (IsReliable && (sequenceNumber > LastAck || (sequenceNumber < 0xff && LastAck > 0xff00)))
_client.SendAck(Type, sequenceNumber, packet.Received);
LastAck = sequenceNumber;

PacketAvailable?.Invoke(combinedPacket);
_logger.Fatal("---> Collected Split Packet");
}
}
else if (packet.Header.IsSplit)
{
_client.SendAck(Type, sequenceNumber, packet.Received);
LastAck = sequenceNumber;
// Enter split mode
InSplitMode = true;
_incomingSplitMessagePackets.Add(sequenceNumber, packet);
}
else
{
if (IsReliable && (sequenceNumber > LastAck || (sequenceNumber < 0xff && LastAck > 0xff00)))
{
_client.SendAck(Type, sequenceNumber, packet.Received);
LastAck = sequenceNumber;
}

PacketAvailable?.Invoke(packet);
PacketAvailable?.Invoke(packet);
}

LastActivity = DateTime.Now;
}

Expand Down Expand Up @@ -298,8 +331,8 @@ public bool SendGSS<T>(T packet, ulong entityId, Enums.GSS.Controllers? controll
/// Send a GSS class to the client
/// </summary>
/// <typeparam name="TPacket">The type of the packet</typeparam>
/// <param name="packet"></param>
/// <param name="entityId"></param>
/// <param name="packet">The packet</param>
/// <param name="entityId">Id of the entity the packet is for</param>
/// <param name="controllerIdParameter">If not provided on the <see cref="GSSMessageAttribute" /> on the packet, the controller Id may be specified here</param>
/// <param name="messageEnumType">Optionally, the enum type containing the message id may be specified for enhanced verbose-level logging</param>
/// <returns>true if the operation succeeded, false in all other cases</returns>
Expand Down Expand Up @@ -343,16 +376,22 @@ public bool SendGSSClass<TPacket>(TPacket packet, ulong entityId, Enums.GSS.Cont
return SendPacketMemory(entityId, messageId, controllerId, ref packetToSend, messageEnumType);
}

public bool SendChecksum(ulong entityId, Enums.GSS.Controllers controllerId, uint checksum)
{
var messageData = Serializer.WritePrimitive(checksum);
return SendPacketMemory(entityId, 2, controllerId, ref messageData);
}

/// <summary>
/// Send an <see cref="IAero" /> package to the client
/// </summary>
/// <typeparam name="TPacket">The type of the packet</typeparam>
/// <param name="packet"></param>
/// <param name="entityId"></param>
/// <param name="packet">The Aero message</param>
/// <param name="entityId">Id of the entity the packet is for</param>
/// <param name="messageIdOverride">Optional way to override the message ID</param>
/// <param name="messageEnumType">Optionally, the enum type containing the message id may be specified for enhanced verbose-level logging</param>
/// <returns>true if the operation succeeded, false in all other cases</returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ArgumentException">The passed packet does not have the AeroMessageIdAttribute</exception>
public bool SendIAero<TPacket>(TPacket packet, ulong entityId = 0, byte messageIdOverride = 0, Type? messageEnumType = null)
where TPacket : class, IAero
{
Expand Down Expand Up @@ -383,6 +422,7 @@ public bool SendIAero<TPacket>(TPacket packet, ulong entityId = 0, byte messageI
}

case AeroMessageIdAttribute.MsgType.Control:
return SendPacketMemoryMatrix(messageId, ref packetMemory, messageEnumType); // Everything's gonna be just fine
default:
throw new ArgumentException("Message type not implemented");
}
Expand All @@ -404,6 +444,33 @@ public bool SendIAeroControllerKeyframe<TPacket>(TPacket packet, ulong entityId,
return SendPacketMemory(entityId, 4, controllerId, ref messageData);
}

public bool SendIAeroControllerRemove<TPacket>(TPacket packet, ulong entityId, ulong playerId)
where TPacket : class, IAero
{
if (typeof(TPacket).GetCustomAttributes(typeof(AeroMessageIdAttribute), false).FirstOrDefault() is not AeroMessageIdAttribute aeroMsgAttr)
{
throw new ArgumentException($"The passed package is required to be annotated with {nameof(AeroMessageIdAttribute)} (Type: {typeof(TPacket).FullName})");
}

var controllerId = (Enums.GSS.Controllers)aeroMsgAttr.ControllerId;
var messageData = new Memory<byte>(new byte[8]);
Serializer.WritePrimitive(playerId).CopyTo(messageData);
return SendPacketMemory(entityId, 5, controllerId, ref messageData);
}

public bool SendIAeroScopeOut<TPacket>(TPacket packet, ulong entityId)
where TPacket : class, IAero
{
if (typeof(TPacket).GetCustomAttributes(typeof(AeroMessageIdAttribute), false).FirstOrDefault() is not AeroMessageIdAttribute aeroMsgAttr)
{
throw new ArgumentException($"The passed package is required to be annotated with {nameof(AeroMessageIdAttribute)} (Type: {typeof(TPacket).FullName})");
}

var controllerId = (Enums.GSS.Controllers)aeroMsgAttr.ControllerId;
var messageData = new Memory<byte>(new byte[0]);
return SendPacketMemory(entityId, 6, controllerId, ref messageData);
}

public bool SendIAeroChanges<TPacket>(TPacket packet, ulong entityId)
where TPacket : class, IAeroViewInterface
{
Expand All @@ -419,13 +486,26 @@ public bool SendIAeroChanges<TPacket>(TPacket packet, ulong entityId)
return SendPacketMemory(entityId, 1, typeCode, ref packetMemory);
}

public bool SendIAeroChanges<TPacket>(TPacket packet, ulong entityId, Memory<byte> packetMemory)
where TPacket : class, IAeroViewInterface
{
if (typeof(TPacket).GetCustomAttributes(typeof(AeroMessageIdAttribute), false).FirstOrDefault() is not AeroMessageIdAttribute aeroMsgAttr)
{
throw new ArgumentException($"The passed package is required to be annotated with {nameof(AeroMessageIdAttribute)} (Type: {typeof(TPacket).FullName})");
}

var typeCode = (Enums.GSS.Controllers)aeroMsgAttr.ControllerId;

return SendPacketMemory(entityId, 1, typeCode, ref packetMemory);
}

/// <summary>
/// Send serialized data of a gss channel packet to the client
/// </summary>
/// <param name="entityId"></param>
/// <param name="messageId"></param>
/// <param name="controllerId"></param>
/// <param name="packetToSend"></param>
/// <param name="entityId">Id of the entity the packet is for</param>
/// <param name="messageId">Message Id relative to the controllerId</param>
/// <param name="controllerId">Typecode of the entity matching the view or controller</param>
/// <param name="packetToSend">Memory buffer</param>
/// <param name="msgEnumType">Optionally, the enum type containing the message id may be specified for enhanced verbose-level logging</param>
/// <returns>true if the operation succeeded, false in all other cases</returns>
/// <exception cref="InvalidOperationException">If <see cref="msgEnumType" /> is not null and does not contain an element with a value equal to <see cref="messageId" /> </exception>
Expand Down Expand Up @@ -472,8 +552,8 @@ private bool SendPacketMemory(ulong entityId,
/// <summary>
/// Send serialized data of a matrix channel packet to the client
/// </summary>
/// <param name="messageId"></param>
/// <param name="packetMemory"></param>
/// <param name="messageId">Id of the matrix message being sent</param>
/// <param name="packetMemory">Memory buffer</param>
/// <param name="msgEnumType">TODO: Optionally, the enum type containing the message id may be specified for enhanced verbose-level logging</param>
/// <returns>true if the operation succeeded, false in all other cases</returns>
private bool SendPacketMemoryMatrix(byte messageId, ref Memory<byte> packetMemory, Type? msgEnumType = null)
Expand All @@ -488,7 +568,7 @@ private bool SendPacketMemoryMatrix(byte messageId, ref Memory<byte> packetMemor
/// <summary>
/// Send data to the client
/// </summary>
/// <param name="packetData"></param>
/// <param name="packetData">Memory buffer</param>
/// <returns>true if the operation succeeded, false in all other cases</returns>
private bool Send(Memory<byte> packetData)
{
Expand Down
3 changes: 3 additions & 0 deletions UdpHosts/GameServer/ChannelType.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#nullable enable
using System.Diagnostics.CodeAnalysis;

namespace GameServer;

[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1602:EnumerationItemsMustBeDocumented", Justification = "See the wiki for more details on how the channels differ: https://github.com/themeldingwars/Documentation/wiki/Game-Server-Protocol-Overview#main-connection")]
public enum ChannelType : byte
{
Control = 0,
Expand Down
Loading
Loading