Core: Added trait 'SurrenderOnDisconnect' and the core changes required to make this work
This commit is contained in:
@@ -21,20 +21,21 @@ namespace OpenRA.Network
|
||||
public List<Slot> Slots = new List<Slot>();
|
||||
public Global GlobalSettings = new Global();
|
||||
|
||||
public Client ClientWithIndex( int clientID )
|
||||
public Client ClientWithIndex(int clientID)
|
||||
{
|
||||
return Clients.SingleOrDefault( c => c.Index == clientID );
|
||||
return Clients.SingleOrDefault(c => c.Index == clientID);
|
||||
}
|
||||
|
||||
public Client ClientInSlot( Slot slot )
|
||||
public Client ClientInSlot(Slot slot)
|
||||
{
|
||||
return Clients.SingleOrDefault( c => c.Slot == slot.Index );
|
||||
return Clients.SingleOrDefault(c => c.Slot == slot.Index);
|
||||
}
|
||||
|
||||
public enum ClientState
|
||||
{
|
||||
NotReady,
|
||||
Ready
|
||||
Ready,
|
||||
Disconnected = 1000
|
||||
}
|
||||
|
||||
public class Client
|
||||
@@ -55,7 +56,7 @@ namespace OpenRA.Network
|
||||
public int Index;
|
||||
public string Bot; // trait name of the bot to initialize in this slot, or null otherwise.
|
||||
public bool Closed; // host has explicitly closed this slot.
|
||||
public string MapPlayer; // playerReference to bind against.
|
||||
public string MapPlayer; // playerReference to bind against.
|
||||
public bool Spectator = false; // Spectating or not
|
||||
// todo: more stuff?
|
||||
}
|
||||
@@ -71,7 +72,7 @@ namespace OpenRA.Network
|
||||
public bool AllowCheats = false;
|
||||
}
|
||||
|
||||
public Session( string[] mods )
|
||||
public Session(string[] mods)
|
||||
{
|
||||
this.GlobalSettings.Mods = mods.ToArray();
|
||||
}
|
||||
@@ -80,27 +81,27 @@ namespace OpenRA.Network
|
||||
{
|
||||
var clientData = new List<MiniYamlNode>();
|
||||
|
||||
foreach( var client in Clients )
|
||||
clientData.Add( new MiniYamlNode( "Client@{0}".F( client.Index ), FieldSaver.Save( client ) ) );
|
||||
foreach (var client in Clients)
|
||||
clientData.Add(new MiniYamlNode("Client@{0}".F(client.Index), FieldSaver.Save(client)));
|
||||
|
||||
foreach( var slot in Slots )
|
||||
clientData.Add( new MiniYamlNode( "Slot@{0}".F( slot.Index ), FieldSaver.Save( slot ) ) );
|
||||
foreach (var slot in Slots)
|
||||
clientData.Add(new MiniYamlNode("Slot@{0}".F(slot.Index), FieldSaver.Save(slot)));
|
||||
|
||||
clientData.Add( new MiniYamlNode( "GlobalSettings", FieldSaver.Save( GlobalSettings ) ) );
|
||||
clientData.Add(new MiniYamlNode("GlobalSettings", FieldSaver.Save(GlobalSettings)));
|
||||
|
||||
return clientData.WriteToString();
|
||||
}
|
||||
|
||||
public static Session Deserialize(string data)
|
||||
{
|
||||
var session = new Session( Game.Settings.Game.Mods );
|
||||
var session = new Session(Game.Settings.Game.Mods);
|
||||
|
||||
var ys = MiniYaml.FromString(data);
|
||||
foreach (var y in ys)
|
||||
{
|
||||
var yy = y.Key.Split('@');
|
||||
|
||||
switch( yy[0] )
|
||||
switch (yy[0])
|
||||
{
|
||||
case "GlobalSettings":
|
||||
FieldLoader.Load(session.GlobalSettings, y.Value);
|
||||
@@ -111,7 +112,7 @@ namespace OpenRA.Network
|
||||
break;
|
||||
|
||||
case "Slot":
|
||||
session.Slots.Add(FieldLoader.Load<Session.Slot>(y.Value ));
|
||||
session.Slots.Add(FieldLoader.Load<Session.Slot>(y.Value));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace OpenRA.Network
|
||||
{
|
||||
static class UnitOrders
|
||||
{
|
||||
static Player FindPlayerByClient( this World world, Session.Client c)
|
||||
static Player FindPlayerByClient(this World world, Session.Client c)
|
||||
{
|
||||
/* todo: this is still a hack.
|
||||
* the cases we're trying to avoid are the extra players on the host's client -- Neutral, other MapPlayers,
|
||||
@@ -25,7 +25,7 @@ namespace OpenRA.Network
|
||||
p => p.ClientIndex == c.Index && p.PlayerName == c.Name);
|
||||
}
|
||||
|
||||
public static void ProcessOrder( OrderManager orderManager, World world, int clientId, Order order )
|
||||
public static void ProcessOrder(OrderManager orderManager, World world, int clientId, Order order)
|
||||
{
|
||||
if (world != null)
|
||||
{
|
||||
@@ -34,103 +34,118 @@ namespace OpenRA.Network
|
||||
return;
|
||||
}
|
||||
|
||||
switch( order.OrderString )
|
||||
switch (order.OrderString)
|
||||
{
|
||||
case "Chat":
|
||||
{
|
||||
var client = orderManager.LobbyInfo.ClientWithIndex( clientId );
|
||||
|
||||
if (Game.IsHost && Game.Settings.Server.Extension != null && !Game.Settings.Server.Extension.OnIngameChat(client, order.TargetString, false))
|
||||
break;
|
||||
|
||||
if (client != null)
|
||||
case "Chat":
|
||||
{
|
||||
var player = world != null ? world.FindPlayerByClient(client) : null;
|
||||
var suffix = (player != null && player.WinState == WinState.Lost) ? " (Dead)" : "";
|
||||
Game.AddChatLine(client.Color1, client.Name+suffix, order.TargetString);
|
||||
}
|
||||
else
|
||||
Game.AddChatLine(Color.White, "(player {0})".F(clientId), order.TargetString);
|
||||
break;
|
||||
}
|
||||
case "TeamChat":
|
||||
{
|
||||
var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
|
||||
var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
|
||||
|
||||
if (Game.IsHost && Game.Settings.Server.Extension != null && !Game.Settings.Server.Extension.OnIngameChat(client, order.TargetString, true))
|
||||
break;
|
||||
if (Game.IsHost && Game.Settings.Server.Extension != null && !Game.Settings.Server.Extension.OnIngameChat(client, order.TargetString, false))
|
||||
break;
|
||||
|
||||
if (client != null)
|
||||
{
|
||||
if (world == null)
|
||||
|
||||
if (client != null)
|
||||
{
|
||||
if (client.Team == orderManager.LocalClient.Team)
|
||||
Game.AddChatLine(client.Color1, client.Name + " (Team)",
|
||||
order.TargetString);
|
||||
var player = world != null ? world.FindPlayerByClient(client) : null;
|
||||
var suffix = (player != null && player.WinState == WinState.Lost) ? " (Dead)" : "";
|
||||
Game.AddChatLine(client.Color1, client.Name + suffix, order.TargetString);
|
||||
}
|
||||
else
|
||||
{
|
||||
var player = world.FindPlayerByClient(client);
|
||||
var display = player != null
|
||||
&& (world.LocalPlayer != null && player.Stances[world.LocalPlayer] == Stance.Ally
|
||||
|| player.WinState == WinState.Lost);
|
||||
Game.AddChatLine(Color.White, "(player {0})".F(clientId), order.TargetString);
|
||||
break;
|
||||
}
|
||||
|
||||
if (display)
|
||||
case "Disconnected": /* reports that the target player disconnected */
|
||||
{
|
||||
var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
|
||||
if (client != null)
|
||||
{
|
||||
client.State = Session.ClientState.Disconnected;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "TeamChat":
|
||||
{
|
||||
var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
|
||||
|
||||
if (Game.IsHost && Game.Settings.Server.Extension != null && !Game.Settings.Server.Extension.OnIngameChat(client, order.TargetString, true))
|
||||
break;
|
||||
|
||||
if (client != null)
|
||||
{
|
||||
if (world == null)
|
||||
{
|
||||
var suffix = (player != null && player.WinState == WinState.Lost) ? " (Dead)" : " (Team)";
|
||||
Game.AddChatLine(client.Color1, client.Name + suffix, order.TargetString);
|
||||
if (client.Team == orderManager.LocalClient.Team)
|
||||
Game.AddChatLine(client.Color1, client.Name + " (Team)",
|
||||
order.TargetString);
|
||||
}
|
||||
else
|
||||
{
|
||||
var player = world.FindPlayerByClient(client);
|
||||
var display = player != null
|
||||
&&
|
||||
(world.LocalPlayer != null &&
|
||||
player.Stances[world.LocalPlayer] == Stance.Ally
|
||||
|| player.WinState == WinState.Lost);
|
||||
|
||||
if (display)
|
||||
{
|
||||
var suffix = (player != null && player.WinState == WinState.Lost)
|
||||
? " (Dead)"
|
||||
: " (Team)";
|
||||
Game.AddChatLine(client.Color1, client.Name + suffix, order.TargetString);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "StartGame":
|
||||
{
|
||||
Game.AddChatLine(Color.White, "Server", "The game has started.");
|
||||
Game.StartGame(orderManager.LobbyInfo.GlobalSettings.Map);
|
||||
break;
|
||||
}
|
||||
case "SyncInfo":
|
||||
{
|
||||
orderManager.LobbyInfo = Session.Deserialize( order.TargetString );
|
||||
|
||||
if( orderManager.FramesAhead != orderManager.LobbyInfo.GlobalSettings.OrderLatency
|
||||
&& !orderManager.GameStarted )
|
||||
case "StartGame":
|
||||
{
|
||||
orderManager.FramesAhead = orderManager.LobbyInfo.GlobalSettings.OrderLatency;
|
||||
Game.Debug( "Order lag is now {0} frames.".F( orderManager.LobbyInfo.GlobalSettings.OrderLatency ) );
|
||||
Game.AddChatLine(Color.White, "Server", "The game has started.");
|
||||
Game.StartGame(orderManager.LobbyInfo.GlobalSettings.Map);
|
||||
break;
|
||||
}
|
||||
case "SyncInfo":
|
||||
{
|
||||
orderManager.LobbyInfo = Session.Deserialize(order.TargetString);
|
||||
|
||||
if (orderManager.FramesAhead != orderManager.LobbyInfo.GlobalSettings.OrderLatency
|
||||
&& !orderManager.GameStarted)
|
||||
{
|
||||
orderManager.FramesAhead = orderManager.LobbyInfo.GlobalSettings.OrderLatency;
|
||||
Game.Debug(
|
||||
"Order lag is now {0} frames.".F(orderManager.LobbyInfo.GlobalSettings.OrderLatency));
|
||||
}
|
||||
Game.SyncLobbyInfo();
|
||||
break;
|
||||
}
|
||||
|
||||
Game.SyncLobbyInfo();
|
||||
break;
|
||||
}
|
||||
case "SetStance":
|
||||
{
|
||||
|
||||
var targetPlayer = order.Player.World.players[order.TargetLocation.X];
|
||||
var newStance = (Stance)order.TargetLocation.Y;
|
||||
case "SetStance":
|
||||
{
|
||||
var targetPlayer = order.Player.World.players[order.TargetLocation.X];
|
||||
var newStance = (Stance)order.TargetLocation.Y;
|
||||
|
||||
if (Game.IsHost && Game.Settings.Server.Extension != null)
|
||||
Game.Settings.Server.Extension.OnIngameSetStance(order.Player, targetPlayer, newStance);
|
||||
|
||||
if (Game.IsHost && Game.Settings.Server.Extension != null)
|
||||
Game.Settings.Server.Extension.OnIngameSetStance(order.Player, targetPlayer, newStance);
|
||||
|
||||
SetPlayerStance(world, order.Player, targetPlayer, newStance);
|
||||
|
||||
// automatically declare war reciprocally
|
||||
if (newStance == Stance.Enemy)
|
||||
SetPlayerStance(world, targetPlayer, order.Player, newStance);
|
||||
SetPlayerStance(world, order.Player, targetPlayer, newStance);
|
||||
|
||||
Game.Debug("{0} has set diplomatic stance vs {1} to {2}".F(
|
||||
order.Player.PlayerName, targetPlayer.PlayerName, newStance));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if( !order.IsImmediate )
|
||||
foreach (var t in order.Subject.TraitsImplementing<IResolveOrder>())
|
||||
t.ResolveOrder(order.Subject, order);
|
||||
break;
|
||||
}
|
||||
// automatically declare war reciprocally
|
||||
if (newStance == Stance.Enemy)
|
||||
SetPlayerStance(world, targetPlayer, order.Player, newStance);
|
||||
|
||||
Game.Debug("{0} has set diplomatic stance vs {1} to {2}".F(
|
||||
order.Player.PlayerName, targetPlayer.PlayerName, newStance));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (!order.IsImmediate)
|
||||
foreach (var t in order.Subject.TraitsImplementing<IResolveOrder>())
|
||||
t.ResolveOrder(order.Subject, order);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user