Add type-safe wrapper around Rpc methods

main
copygirl 4 years ago
parent 2c63e07911
commit d66f16c1aa
  1. 7
      src/EscapeMenuAppearance.cs
  2. 1
      src/EscapeMenuWorld.cs
  3. 4
      src/IO/WorldSave.cs
  4. 8
      src/Items/CreativeBuilding.cs
  5. 8
      src/Items/Items.cs
  6. 12
      src/Items/Weapon.cs
  7. 2
      src/Objects/LocalPlayer.cs
  8. 1
      src/Objects/Player.cs
  9. 12
      src/Scenes/Server.cs
  10. 44
      src/Utility/RPC.cs

@ -20,8 +20,8 @@ public class EscapeMenuAppearance : CenterContainer
ColorSlider.Value = GD.Randf();
ColorPreview.Modulate = Color.FromHsv((float)ColorSlider.Value, 1.0F, 1.0F);
this.GetClient().LocalPlayerSpawned += (player) => player.RpcId(1,
nameof(Player.ChangeAppearance), DisplayName.Text, ColorPreview.Modulate);
this.GetClient().LocalPlayerSpawned += (player)
=> RPC.Reliable(1, player.ChangeAppearance, DisplayName.Text, ColorPreview.Modulate);
}
#pragma warning disable IDE0051
@ -49,7 +49,6 @@ public class EscapeMenuAppearance : CenterContainer
if (IsVisibleInTree()) return;
var client = this.GetClient();
if (client.Status == NetworkedMultiplayerPeer.ConnectionStatus.Connected)
client.LocalPlayer.RpcId(1, nameof(Player.ChangeAppearance),
DisplayName.Text, ColorPreview.Modulate);
RPC.Reliable(1, client.LocalPlayer.ChangeAppearance, DisplayName.Text, ColorPreview.Modulate);
}
}

@ -105,6 +105,7 @@ public class EscapeMenuWorld : CenterContainer
// Reset players' positions.
foreach (var player in server.GetWorld().Players)
// Can't use RPC helper method here since player is not a LocalPlayer here.
player.RpcId(player.NetworkID, nameof(LocalPlayer.ResetPosition), Vector2.Zero);
save.ReadDataIntoWorld(server.GetWorld());

@ -75,8 +75,8 @@ public class WorldSave
public void ReadDataIntoWorld(World world)
{
world.Rpc(nameof(World.ClearBlocks));
RPC.Reliable(world.ClearBlocks);
foreach (var (position, color, unbreakable) in Blocks)
world.Rpc(nameof(World.SpawnBlock), position.X, position.Y, color, unbreakable);
RPC.Reliable(world.SpawnBlock, position.X, position.Y, color, unbreakable);
}
}

@ -57,14 +57,14 @@ public class CreativeBuilding : Node2D
if (_currentMode == BuildMode.Placing) {
if (!_canBuild) _currentMode = null;
else if (!Input.IsActionPressed("interact_primary")) {
RpcId(1, nameof(PlaceLine), _startPos.X, _startPos.Y, _direction, _length);
RPC.Reliable(1, PlaceLine, _startPos.X, _startPos.Y, _direction, _length);
_currentMode = null;
}
}
if (_currentMode == BuildMode.Breaking) {
if (!Input.IsActionPressed("interact_secondary")) {
RpcId(1, nameof(BreakLine), _startPos.X, _startPos.Y, _direction, _length);
RPC.Reliable(1, BreakLine, _startPos.X, _startPos.Y, _direction, _length);
_currentMode = null;
}
}
@ -121,7 +121,7 @@ public class CreativeBuilding : Node2D
foreach (var pos in GetBlockPositions(start, direction, length)) {
if (world.GetBlockAt(pos) != null) continue;
var color = Player.Color.Blend(Color.FromHsv(0.0F, 0.0F, GD.Randf(), 0.2F));
world.Rpc(nameof(World.SpawnBlock), pos.X, pos.Y, color, false);
RPC.Reliable(world.SpawnBlock, pos.X, pos.Y, color, false);
}
}
@ -137,7 +137,7 @@ public class CreativeBuilding : Node2D
foreach (var pos in GetBlockPositions(start, direction, length)) {
var block = world.GetBlockAt(pos);
if (block?.Unbreakable != false) continue;
world.Rpc(nameof(World.Despawn), world.GetPathTo(block));
RPC.Reliable(world.Despawn, world.GetPathTo(block));
}
}
}

@ -39,16 +39,14 @@ public class Items : Node2D, IItems
_current = node;
if (sendRpc) {
if (this.GetGame() is Server) Rpc(nameof(DoSetCurrent), _current?.Name);
else RpcId(1, nameof(DoSetCurrent), _current?.Name);
if (this.GetGame() is Server) RPC.Reliable(DoSetCurrent, _current?.Name);
else RPC.Reliable(1, DoSetCurrent, _current?.Name);
}
}
[Remote]
public void DoSetCurrent(string name)
{
if (this.GetGame() is Server) {
if (GetTree().GetRpcSenderId() != Player.NetworkID) return;
}
if ((this.GetGame() is Server) && (Player.NetworkID != GetTree().GetRpcSenderId())) return;
var node = (name != null) ? GetNode<Node2D>(name) : null;
SetCurrent(node, this.GetGame() is Server);
}

@ -125,7 +125,7 @@ public class Weapon : Sprite
AimDirection = Cursor.Position.AngleToPoint(Player.Position) - angleC;
// FIXME: Angle calculation when cursor is too close to player.
RpcUnreliableId(1, nameof(SendAimAngle), AimDirection);
RPC.Unreliable(1, SendAimAngle, AimDirection);
Update();
}
} else {
@ -147,7 +147,7 @@ public class Weapon : Sprite
if (Player.NetworkID != GetTree().GetRpcSenderId()) return;
// TODO: Verify input.
// if ((value < 0) || (value > Mathf.Tau)) return;
Rpc(nameof(SendAimAngle), value);
RPC.Unreliable(SendAimAngle, value);
} else if (!(Player is LocalPlayer))
AimDirection = value;
}
@ -157,7 +157,7 @@ public class Weapon : Sprite
{
var seed = unchecked((int)GD.Randi());
if (!FireInternal(AimDirection, Scale.y > 0, seed)) return;
RpcId(1, nameof(SendFire), AimDirection, Scale.y > 0, seed);
RPC.Reliable(1, SendFire, AimDirection, Scale.y > 0, seed);
((LocalPlayer)Player).Velocity -= Mathf.Polar2Cartesian(Knockback, Rotation);
}
@ -198,14 +198,14 @@ public class Weapon : Sprite
if (Player.NetworkID != GetTree().GetRpcSenderId()) return;
// TODO: Verify input.
if (FireInternal(aimDirection, toRight, seed))
Rpc(nameof(SendFire), aimDirection, toRight, seed);
RPC.Reliable(SendFire, aimDirection, toRight, seed);
} else if (!(Player is LocalPlayer))
FireInternal(aimDirection, toRight, seed);
}
private void Reload()
{ if (ReloadInternal()) RpcId(1, nameof(SendReload)); }
{ if (ReloadInternal()) RPC.Reliable(1, SendReload); }
private bool ReloadInternal()
{
@ -220,7 +220,7 @@ public class Weapon : Sprite
{
if (this.GetGame() is Server) {
if (Player.NetworkID != GetTree().GetRpcSenderId()) return;
if (ReloadInternal()) Rpc(nameof(SendReload));
if (ReloadInternal()) RPC.Reliable(SendReload);
} else if (!(Player is LocalPlayer))
ReloadInternal();
}

@ -23,7 +23,7 @@ public class LocalPlayer : Player
public override void _Process(float delta)
{
base._Process(delta);
RpcUnreliableId(1, nameof(Player.Move), Position);
RPC.Unreliable(1, Move, Position);
}
public override void _PhysicsProcess(float delta)

@ -31,6 +31,7 @@ public class Player : KinematicBody2D, IInitializable
public override void _Process(float delta)
{
if ((Position.y > 9000) && (this.GetGame() is Server))
// Can't use RPC helper method here since player is not a LocalPlayer here.
RpcId(NetworkID, nameof(LocalPlayer.ResetPosition), Vector2.Zero);
}

@ -83,23 +83,23 @@ public class Server : Game
var world = this.GetWorld();
foreach (var player in world.Players) {
world.RpcId(networkID, nameof(World.SpawnPlayer), player.NetworkID, player.Position);
RPC.Reliable(networkID, world.SpawnPlayer, player.NetworkID, player.Position);
// Send player's appearance.
player.Rset(nameof(Player.DisplayName), player.DisplayName);
player.Rset(nameof(Player.Color), player.Color);
// Send player's currently equipped item.
if (player.Items.Current != null) ((Node2D)player.Items).RpcId(
networkID, nameof(Items.DoSetCurrent), player.Items.Current.Name);
if (player.Items.Current != null) RPC.Reliable(networkID,
((Items)player.Items).DoSetCurrent, player.Items.Current.Name);
}
foreach (var block in world.Blocks)
world.RpcId(networkID, nameof(World.SpawnBlock),
RPC.Reliable(networkID, world.SpawnBlock,
block.Position.X, block.Position.Y,
block.Color, block.Unbreakable);
world.Rpc(nameof(World.SpawnPlayer), networkID, Vector2.Zero);
RPC.Reliable(world.SpawnPlayer, networkID, Vector2.Zero);
if (IsSingleplayer) LocalPlayer = world.GetPlayer(networkID);
}
}
@ -112,6 +112,6 @@ public class Server : Game
// Local player stays around for reconnecting.
if (LocalPlayer == player) return;
world.Rpc(nameof(World.Despawn), world.GetPathTo(player));
RPC.Reliable(world.Despawn, world.GetPathTo(player));
}
}

@ -0,0 +1,44 @@
using System;
using Godot;
public static class RPC
{
public static void Reliable(Action action) => GetNode(action).Rpc(action.Method.Name);
public static void Reliable<T>(Action<T> action, T arg) => GetNode(action).Rpc(action.Method.Name, arg);
public static void Reliable<T0, T1>(Action<T0, T1> action, T0 arg0, T1 arg1) => GetNode(action).Rpc(action.Method.Name, arg0, arg1);
public static void Reliable<T0, T1, T2>(Action<T0, T1, T2> action, T0 arg0, T1 arg1, T2 arg2) => GetNode(action).Rpc(action.Method.Name, arg0, arg1, arg2);
public static void Reliable<T0, T1, T2, T3>(Action<T0, T1, T2, T3> action, T0 arg0, T1 arg1, T2 arg2, T3 arg3) => GetNode(action).Rpc(action.Method.Name, arg0, arg1, arg2, arg3);
public static void Reliable<T0, T1, T2, T3, T4>(Action<T0, T1, T2, T3, T4> action, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) => GetNode(action).Rpc(action.Method.Name, arg0, arg1, arg2, arg3, arg4);
public static void Reliable<T0, T1, T2, T3, T4, T5>(Action<T0, T1, T2, T3, T4, T5> action, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) => GetNode(action).Rpc(action.Method.Name, arg0, arg1, arg2, arg3, arg4, arg5);
public static void Reliable<T0, T1, T2, T3, T4, T5, T6>(Action<T0, T1, T2, T3, T4, T5, T6> action, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) => GetNode(action).Rpc(action.Method.Name, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
public static void Reliable(int networkID, Action action) => GetNode(action).RpcId(networkID, action.Method.Name);
public static void Reliable<T>(int networkID, Action<T> action, T arg) => GetNode(action).RpcId(networkID, action.Method.Name, arg);
public static void Reliable<T0, T1>(int networkID, Action<T0, T1> action, T0 arg0, T1 arg1) => GetNode(action).RpcId(networkID, action.Method.Name, arg0, arg1);
public static void Reliable<T0, T1, T2>(int networkID, Action<T0, T1, T2> action, T0 arg0, T1 arg1, T2 arg2) => GetNode(action).RpcId(networkID, action.Method.Name, arg0, arg1, arg2);
public static void Reliable<T0, T1, T2, T3>(int networkID, Action<T0, T1, T2, T3> action, T0 arg0, T1 arg1, T2 arg2, T3 arg3) => GetNode(action).RpcId(networkID, action.Method.Name, arg0, arg1, arg2, arg3);
public static void Reliable<T0, T1, T2, T3, T4>(int networkID, Action<T0, T1, T2, T3, T4> action, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) => GetNode(action).RpcId(networkID, action.Method.Name, arg0, arg1, arg2, arg3, arg4);
public static void Reliable<T0, T1, T2, T3, T4, T5>(int networkID, Action<T0, T1, T2, T3, T4, T5> action, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) => GetNode(action).RpcId(networkID, action.Method.Name, arg0, arg1, arg2, arg3, arg4, arg5);
public static void Reliable<T0, T1, T2, T3, T4, T5, T6>(int networkID, Action<T0, T1, T2, T3, T4, T5, T6> action, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) => GetNode(action).RpcId(networkID, action.Method.Name, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
public static void Unreliable(Action action) => GetNode(action).RpcUnreliable(action.Method.Name);
public static void Unreliable<T>(Action<T> action, T arg) => GetNode(action).RpcUnreliable(action.Method.Name, arg);
public static void Unreliable<T0, T1>(Action<T0, T1> action, T0 arg0, T1 arg1) => GetNode(action).RpcUnreliable(action.Method.Name, arg0, arg1);
public static void Unreliable<T0, T1, T2>(Action<T0, T1, T2> action, T0 arg0, T1 arg1, T2 arg2) => GetNode(action).RpcUnreliable(action.Method.Name, arg0, arg1, arg2);
public static void Unreliable<T0, T1, T2, T3>(Action<T0, T1, T2, T3> action, T0 arg0, T1 arg1, T2 arg2, T3 arg3) => GetNode(action).RpcUnreliable(action.Method.Name, arg0, arg1, arg2, arg3);
public static void Unreliable<T0, T1, T2, T3, T4>(Action<T0, T1, T2, T3, T4> action, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) => GetNode(action).RpcUnreliable(action.Method.Name, arg0, arg1, arg2, arg3, arg4);
public static void Unreliable<T0, T1, T2, T3, T4, T5>(Action<T0, T1, T2, T3, T4, T5> action, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) => GetNode(action).RpcUnreliable(action.Method.Name, arg0, arg1, arg2, arg3, arg4, arg5);
public static void Unreliable<T0, T1, T2, T3, T4, T5, T6>(Action<T0, T1, T2, T3, T4, T5, T6> action, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) => GetNode(action).RpcUnreliable(action.Method.Name, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
public static void Unreliable(int networkID, Action action) => GetNode(action).RpcUnreliableId(networkID, action.Method.Name);
public static void Unreliable<T>(int networkID, Action<T> action, T arg) => GetNode(action).RpcUnreliableId(networkID, action.Method.Name, arg);
public static void Unreliable<T0, T1>(int networkID, Action<T0, T1> action, T0 arg0, T1 arg1) => GetNode(action).RpcUnreliableId(networkID, action.Method.Name, arg0, arg1);
public static void Unreliable<T0, T1, T2>(int networkID, Action<T0, T1, T2> action, T0 arg0, T1 arg1, T2 arg2) => GetNode(action).RpcUnreliableId(networkID, action.Method.Name, arg0, arg1, arg2);
public static void Unreliable<T0, T1, T2, T3>(int networkID, Action<T0, T1, T2, T3> action, T0 arg0, T1 arg1, T2 arg2, T3 arg3) => GetNode(action).RpcUnreliableId(networkID, action.Method.Name, arg0, arg1, arg2, arg3);
public static void Unreliable<T0, T1, T2, T3, T4>(int networkID, Action<T0, T1, T2, T3, T4> action, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) => GetNode(action).RpcUnreliableId(networkID, action.Method.Name, arg0, arg1, arg2, arg3, arg4);
public static void Unreliable<T0, T1, T2, T3, T4, T5>(int networkID, Action<T0, T1, T2, T3, T4, T5> action, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) => GetNode(action).RpcUnreliableId(networkID, action.Method.Name, arg0, arg1, arg2, arg3, arg4, arg5);
public static void Unreliable<T0, T1, T2, T3, T4, T5, T6>(int networkID, Action<T0, T1, T2, T3, T4, T5, T6> action, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) => GetNode(action).RpcUnreliableId(networkID, action.Method.Name, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
private static Node GetNode(Delegate action) => (action.Target as Node) ?? throw new ArgumentException(
$"Target ({action.Target?.GetType().ToString() ?? "null"}) must be a Node", nameof(action));
}
Loading…
Cancel
Save