Completely destroyed game

Looks like a lot more than just netcode is getting rewritten. Removing coroutines because there are better ways of handling asynchronous tasks, removing filestream because that's to be reimplemented later
This commit is contained in:
juanjp600
2016-08-30 19:59:14 -03:00
parent 37ffd64490
commit 9416eb64d7
31 changed files with 72 additions and 1437 deletions

View File

@@ -101,7 +101,6 @@
<Compile Include="Source\Characters\Jobs\Skill.cs" />
<Compile Include="Source\Characters\Jobs\SkillPrefab.cs" />
<Compile Include="Source\ContentPackage.cs" />
<Compile Include="Source\CoroutineManager.cs" />
<Compile Include="Source\Events\Missions\CargoMission.cs" />
<Compile Include="Source\Events\Missions\Mission.cs" />
<Compile Include="Source\Events\Missions\MonsterMission.cs" />
@@ -150,8 +149,6 @@
<Compile Include="Source\Networking\BanList.cs" />
<Compile Include="Source\Networking\ChatMessage.cs" />
<Compile Include="Source\Networking\Client.cs" />
<Compile Include="Source\Networking\FileStreamReceiver.cs" />
<Compile Include="Source\Networking\FileStreamSender.cs" />
<Compile Include="Source\Networking\GameServerLogin.cs" />
<Compile Include="Source\Networking\NetBufferExtensions.cs" />
<Compile Include="Source\Networking\NetConfig.cs" />

View File

@@ -47,7 +47,7 @@ namespace Barotrauma
{
if (!character.SelectedItems.Contains(weapon))
{
character.Inventory.TryPutItem(weapon, 3, true, false);
character.Inventory.TryPutItem(weapon, 3, false);
weapon.Equip(character);
}
character.CursorPosition = enemy.Position;

View File

@@ -60,7 +60,7 @@ namespace Barotrauma
if (existingItem != null) existingItem.Drop(character);
character.Inventory.RemoveItem(itemToContain);
container.Inventory.TryPutItem(itemToContain, null, false);
container.Inventory.TryPutItem(itemToContain, null);
}
else
{

View File

@@ -85,7 +85,7 @@ namespace Barotrauma
if (character.Inventory.Items[i] == null) continue;
//try to move the existing item to LimbSlot.Any and continue if successful
if (character.Inventory.TryPutItem(character.Inventory.Items[i], new List<InvSlotType>() { InvSlotType.Any }, false)) continue;
if (character.Inventory.TryPutItem(character.Inventory.Items[i], new List<InvSlotType>() { InvSlotType.Any })) continue;
//if everything else fails, simply drop the existing item
character.Inventory.Items[i].Drop();
@@ -97,7 +97,7 @@ namespace Barotrauma
if (targetSlot > -1 && character.Inventory.IsInLimbSlot(targetItem, InvSlotType.Any))
{
character.Inventory.TryPutItem(targetItem, targetSlot, true, false);
character.Inventory.TryPutItem(targetItem, targetSlot, false);
}
}
else

View File

@@ -591,7 +591,7 @@ namespace Barotrauma
if (item == null) continue;
item.Pick(this, true, true, true);
inventory.TryPutItem(item, i, false, false);
inventory.TryPutItem(item, i, false);
}
}
}
@@ -795,7 +795,7 @@ namespace Barotrauma
{
if (Vector2.Distance(selectedCharacter.WorldPosition, WorldPosition) > 300.0f || !selectedCharacter.CanBeSelected)
{
DeselectCharacter(controlled == this);
DeselectCharacter();
}
}
@@ -944,16 +944,14 @@ namespace Barotrauma
return closestCharacter;
}
private void SelectCharacter(Character character, bool createNetworkEvent = true)
private void SelectCharacter(Character character)
{
if (character == null) return;
selectedCharacter = character;
if (createNetworkEvent) new NetworkEvent(NetworkEventType.SelectCharacter, ID, true, selectedCharacter.ID);
}
private void DeselectCharacter(bool createNetworkEvent = true)
private void DeselectCharacter()
{
if (selectedCharacter == null) return;
@@ -963,8 +961,6 @@ namespace Barotrauma
}
selectedCharacter = null;
if (createNetworkEvent) new NetworkEvent(NetworkEventType.SelectCharacter, ID, true, (ushort)0);
}
/// <summary>
@@ -1063,13 +1059,7 @@ namespace Barotrauma
closestItem.IsHighlighted = true;
if (!LockHands && closestItem.Pick(this))
{
new NetworkEvent(NetworkEventType.PickItem, ID, true,
new int[]
{
closestItem.ID,
IsKeyHit(InputType.Select) ? 1 : 0,
IsKeyHit(InputType.Use) ? 1 : 0
});
}
}
@@ -1077,7 +1067,7 @@ namespace Barotrauma
{
if (selectedCharacter != null)
{
DeselectCharacter(controlled == this);
DeselectCharacter();
}
else if (closestCharacter != null && closestCharacter.IsHumanoid && closestCharacter.CanBeSelected)
{
@@ -1087,7 +1077,7 @@ namespace Barotrauma
}
else
{
if (selectedCharacter != null) DeselectCharacter(controlled==this);
if (selectedCharacter != null) DeselectCharacter();
selectedConstruction = null;
closestItem = null;
closestCharacter = null;
@@ -1486,13 +1476,11 @@ namespace Barotrauma
GameMain.NetworkMember.AddChatMessage(chatMessage, ChatMessageType.Dead);
GameMain.LightManager.LosEnabled = false;
controlled = null;
new NetworkEvent(NetworkEventType.KillCharacter, ID, true, causeOfDeath);
}
//if it's an ai Character, only let the server kill it
else if (GameMain.Server != null && this is AICharacter)
{
new NetworkEvent(NetworkEventType.KillCharacter, ID, false, causeOfDeath);
}
//don't kill the Character unless received a message about the Character dying
else if (!isNetworkMessage)

View File

@@ -107,9 +107,7 @@ namespace Barotrauma
{
limb.pullJoint.Enabled = false;
}
new NetworkEvent(NetworkEventType.SelectCharacter, Character.Controlled.ID, true, Character.Controlled.SelectedCharacter.ID);
return true;
};
}

View File

@@ -175,7 +175,7 @@ namespace Barotrauma
for (int i = 0; i < character.Inventory.Items.Length; i++)
{
if (character.Inventory.Items[i] == null) continue;
husk.Inventory.TryPutItem(character.Inventory.Items[i], i, false, true);
husk.Inventory.TryPutItem(character.Inventory.Items[i], i, true);
}
character.Enabled = false;

View File

@@ -112,11 +112,11 @@ namespace Barotrauma
List<InvSlotType> allowedSlots = new List<InvSlotType>(item.AllowedSlots);
allowedSlots.Remove(InvSlotType.Any);
character.Inventory.TryPutItem(item, allowedSlots, false);
character.Inventory.TryPutItem(item, allowedSlots);
}
else
{
character.Inventory.TryPutItem(item, item.AllowedSlots, false);
character.Inventory.TryPutItem(item, item.AllowedSlots);
}
if (item.Prefab.Name == "ID Card" && spawnPoint != null)

View File

@@ -307,7 +307,7 @@ namespace Barotrauma
}
else
{
NetworkEvent.Events.Clear();
}
GUI.Update((float)deltaTime);
@@ -351,13 +351,6 @@ namespace Barotrauma
}
static bool waitForKeyHit = true;
public static CoroutineHandle ShowLoading(IEnumerable<object> loader, bool waitKeyHit = true)
{
waitForKeyHit = waitKeyHit;
titleScreenOpen = true;
TitleScreen.LoadState = null;
return CoroutineManager.StartCoroutine(TitleScreen.DoLoading(loader));
}
protected override void OnExiting(object sender, EventArgs args)
{

View File

@@ -100,7 +100,6 @@ namespace Barotrauma
ushort itemID = Items[slotIndex].ID;
Items[slotIndex].ApplyStatusEffects(ActionType.OnUse, 1.0f, character);
new NetworkEvent(NetworkEventType.ApplyStatusEffect, character.ID, true, itemID);
return true;
}
@@ -142,7 +141,7 @@ namespace Barotrauma
/// <summary>
/// If there is room, puts the item in the inventory and returns true, otherwise returns false
/// </summary>
public override bool TryPutItem(Item item, List<InvSlotType> allowedSlots = null, bool createNetworkEvent = true)
public override bool TryPutItem(Item item, List<InvSlotType> allowedSlots = null)
{
if (allowedSlots == null || ! allowedSlots.Any()) return false;
@@ -153,7 +152,7 @@ namespace Barotrauma
{
if (Items[i] != null || limbSlots[i] != InvSlotType.Any) continue;
PutItem(item, i, createNetworkEvent);
PutItem(item, i);
item.Unequip(character);
return true;
}
@@ -179,7 +178,7 @@ namespace Barotrauma
{
if (allowedSlot.HasFlag(limbSlots[i]) && Items[i] == null)
{
PutItem(item, i, createNetworkEvent, !placed);
PutItem(item, i, !placed);
item.Equip(character);
placed = true;
}
@@ -195,7 +194,7 @@ namespace Barotrauma
return placed;
}
public override bool TryPutItem(Item item, int index, bool allowSwapping, bool createNetworkEvent)
public override bool TryPutItem(Item item, int index, bool allowSwapping)
{
//there's already an item in the slot
if (Items[index] != null)
@@ -208,9 +207,9 @@ namespace Barotrauma
System.Diagnostics.Debug.Assert(Items[index] != null);
Inventory otherInventory = Items[index].ParentInventory;
if (otherInventory != null && otherInventory.Owner!=null && createNetworkEvent)
if (otherInventory != null && otherInventory.Owner!=null)
{
new Networking.NetworkEvent(Networking.NetworkEventType.InventoryUpdate, otherInventory.Owner.ID, true, true);
}
combined = true;
@@ -225,10 +224,10 @@ namespace Barotrauma
Items[currentIndex] = null;
Items[index] = null;
//if the item in the slot can be moved to the slot of the moved item
if (TryPutItem(existingItem, currentIndex, false, false) &&
TryPutItem(item, index, false, false))
if (TryPutItem(existingItem, currentIndex, false) &&
TryPutItem(item, index, false))
{
new Networking.NetworkEvent(Networking.NetworkEventType.InventoryUpdate, Owner.ID, true, true);
}
else
{
@@ -250,7 +249,7 @@ namespace Barotrauma
if (!item.AllowedSlots.Contains(InvSlotType.Any)) return false;
if (Items[index] != null) return Items[index] == item;
PutItem(item, index, createNetworkEvent, true);
PutItem(item, index, true);
return true;
}
@@ -276,7 +275,7 @@ namespace Barotrauma
if (!slotsFree) return false;
return TryPutItem(item, new List<InvSlotType>() {placeToSlots}, createNetworkEvent);
return TryPutItem(item, new List<InvSlotType>() {placeToSlots});
}
public void DrawOwn(SpriteBatch spriteBatch, Vector2 offset)
@@ -492,8 +491,7 @@ namespace Barotrauma
else
{
DropItem(draggingItem);
new NetworkEvent(NetworkEventType.DropItem, draggingItem.ID, true);
//draggingItem = null;
}
}

View File

@@ -63,17 +63,7 @@ namespace Barotrauma.Items.Components
if (PickingTime>0.0f)
{
CoroutineManager.StartCoroutine(WaitForPick(picker, PickingTime));
//create a networkevent here, because the item doesn't count as picked yet and the character won't create one
new NetworkEvent(NetworkEventType.PickItem, picker.ID, true,
new int[]
{
item.ID,
picker.IsKeyHit(InputType.Select) ? 1 : 0,
picker.IsKeyHit(InputType.Use) ? 1 : 0
});
return false;
}
else
@@ -86,7 +76,7 @@ namespace Barotrauma.Items.Components
private bool OnPicked(Character picker)
{
if (picker.Inventory.TryPutItem(item, allowedSlots, picker == Character.Controlled))
if (picker.Inventory.TryPutItem(item, allowedSlots))
{
if (!picker.HasSelectedItem(item) && item.body != null) item.body.Enabled = false;
this.picker = picker;

View File

@@ -253,7 +253,7 @@ namespace Barotrauma.Items.Components
Item item = MapEntity.FindEntityByID(itemIds[i]) as Item;
if (item == null) continue;
Inventory.TryPutItem(item, i, false, false);
Inventory.TryPutItem(item, i, false);
}
itemIds = null;

View File

@@ -141,9 +141,7 @@ namespace Barotrauma
Item item = frame.UserData as Item;
if (item == null) return true;
new NetworkEvent(NetworkEventType.ItemFixed, item.ID, true, (byte)item.FixRequirements.IndexOf(requirement) );
return true;
}

View File

@@ -93,21 +93,21 @@ namespace Barotrauma
/// <summary>
/// If there is room, puts the item in the inventory and returns true, otherwise returns false
/// </summary>
public virtual bool TryPutItem(Item item, List<InvSlotType> allowedSlots = null, bool createNetworkEvent = true)
public virtual bool TryPutItem(Item item, List<InvSlotType> allowedSlots = null)
{
int slot = FindAllowedSlot(item);
if (slot < 0) return false;
PutItem(item, slot, createNetworkEvent);
PutItem(item, slot);
return true;
}
public virtual bool TryPutItem(Item item, int i, bool allowSwapping, bool createNetworkEvent)
public virtual bool TryPutItem(Item item, int i, bool allowSwapping)
{
if (Owner == null) return false;
if (CanBePut(item,i))
{
PutItem(item, i, createNetworkEvent);
PutItem(item, i);
return true;
}
else
@@ -116,7 +116,7 @@ namespace Barotrauma
}
}
protected void PutItem(Item item, int i, bool createNetworkEvent, bool removeItem = true)
protected void PutItem(Item item, int i, bool removeItem = true)
{
if (Owner == null) return;
@@ -132,8 +132,6 @@ namespace Barotrauma
{
item.body.Enabled = false;
}
if (createNetworkEvent) new NetworkEvent(NetworkEventType.InventoryUpdate, Owner.ID, true, true);
}
public Item FindItem(string itemName)
@@ -216,7 +214,7 @@ namespace Barotrauma
{
if (Owner!=null)
{
new NetworkEvent(NetworkEventType.InventoryUpdate, Owner.ID, true);
}
DropItem(draggingItem);

View File

@@ -165,8 +165,6 @@ namespace Barotrauma
condition = MathHelper.Clamp(value, 0.0f, 100.0f);
if (condition == 0.0f && prev>0.0f)
{
new NetworkEvent(this.ID, false);
ApplyStatusEffects(ActionType.OnBroken, 1.0f, null);
foreach (FixRequirement req in FixRequirements)
{
@@ -719,7 +717,7 @@ namespace Barotrauma
Vector2 moveAmount = body.SimPosition - body.LastSentPosition;
if (parentInventory == null && moveAmount != Vector2.Zero && moveAmount.Length() > NetConfig.ItemPosUpdateDistance)
{
new NetworkEvent(NetworkEventType.PhysicsBodyPosition, ID, false);
}
Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.SimPosition);
@@ -784,7 +782,6 @@ namespace Barotrauma
if (ImpactTolerance > 0.0f && impact > ImpactTolerance)
{
ApplyStatusEffects(ActionType.OnImpact, 1.0f);
new NetworkEvent(NetworkEventType.ApplyStatusEffect, this.ID, false, ActionType.OnImpact);
}
var containedItems = ContainedItems;
@@ -1384,7 +1381,7 @@ namespace Barotrauma
return isCombined;
}
public void Drop(Character dropper = null, bool createNetworkEvent = true)
public void Drop(Character dropper = null)
{
//if (dropper == Character.Controlled)
// new NetworkEvent(NetworkEventType.DropItem, ID, true);
@@ -1450,9 +1447,7 @@ namespace Barotrauma
if (objectProperty.TrySetValue(text))
{
textBox.Text = text;
new NetworkEvent(NetworkEventType.UpdateProperty, ID, true, objectProperty.Name);
return true;
}
else
@@ -1620,9 +1615,6 @@ namespace Barotrauma
public void NewComponentEvent(ItemComponent ic, bool isClient, bool isImportant)
{
int index = components.IndexOf(ic);
new NetworkEvent(isImportant ?
NetworkEventType.ImportantComponentUpdate : NetworkEventType.ComponentUpdate, ID, isClient, index);
}
public override void Remove()

View File

@@ -44,9 +44,9 @@ namespace Barotrauma
return (item!=null && Items[i]==null && container.CanBeContained(item));
}
public override bool TryPutItem(Item item, int i, bool allowSwapping, bool createNetworkEvent)
public override bool TryPutItem(Item item, int i, bool allowSwapping)
{
bool wasPut = base.TryPutItem(item, i, allowSwapping, createNetworkEvent);
bool wasPut = base.TryPutItem(item, i, allowSwapping);
if (wasPut)
{

View File

@@ -74,7 +74,7 @@ namespace Barotrauma
AddToSpawnedList(item);
var inventory = (Inventory)itemInfo.Second;
inventory.TryPutItem(item, null, false);
inventory.TryPutItem(item, null);
items.Add(item);
//inventories.Add(inventory);

View File

@@ -61,10 +61,10 @@ namespace Barotrauma
get { return hull; }
}
public FireSource(Vector2 worldPosition, Hull spawningHull = null, bool networkEvent=false)
public FireSource(Vector2 worldPosition, Hull spawningHull = null)
{
hull = Hull.FindHull(worldPosition, spawningHull);
if (hull == null || (!networkEvent && GameMain.Client!=null)) return;
if (hull == null || (GameMain.Client!=null)) return;
if (fireSoundBasic==null)
{
@@ -72,7 +72,7 @@ namespace Barotrauma
fireSoundLarge = Sound.Load("Content/Sounds/firelarge.ogg");
}
hull.AddFireSource(this, !networkEvent);
hull.AddFireSource(this);
Submarine = hull.Submarine;
@@ -338,9 +338,9 @@ namespace Barotrauma
if (size.X < 1.0f) Remove();
}
public void Remove(bool isNetworkEvent = false)
public void Remove()
{
if (!isNetworkEvent && GameMain.Client != null) return;
if (GameMain.Client != null) return;
lightSource.Remove();

View File

@@ -343,13 +343,9 @@ namespace Barotrauma
}
public void AddFireSource(FireSource fireSource, bool createNetworkEvent = true)
public void AddFireSource(FireSource fireSource)
{
fireSources.Add(fireSource);
if (createNetworkEvent)
{
new Networking.NetworkEvent(Networking.NetworkEventType.ImportantEntityUpdate, this.ID, false);
}
}
public override void Update(Camera cam, float deltaTime)
@@ -446,7 +442,7 @@ namespace Barotrauma
if (Math.Abs(lastSentVolume - volume) > FullVolume * 0.1f ||
Math.Abs(lastSentOxygen - OxygenPercentage) > 5f)
{
new Networking.NetworkEvent(ID, false);
}
if (!update)
@@ -545,7 +541,6 @@ namespace Barotrauma
public void RemoveFire(FireSource fire)
{
fireSources.Remove(fire);
new Networking.NetworkEvent(Networking.NetworkEventType.ImportantEntityUpdate, this.ID, false);
}
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)

View File

@@ -572,7 +572,6 @@ namespace Barotrauma
if (damage != sections[sectionIndex].damage && Math.Abs(sections[sectionIndex].lastSentDamage - damage)>5.0f)
{
new NetworkEvent(NetworkEventType.ImportantEntityUpdate, ID, false);
//sections[sectionIndex].lastSentDamage = damage;
}

View File

@@ -474,7 +474,6 @@ namespace Barotrauma
if (networkUpdateTimer < 0.0f)
{
new Networking.NetworkEvent(ID, false);
networkUpdateTimer = 1.0f;
}

View File

@@ -42,9 +42,7 @@ namespace Barotrauma.Networking
public List<JobPrefab> jobPreferences;
public JobPrefab assignedJob;
public FileStreamSender FileStreamSender;
public float deleteDisconnectedTimer;
public ClientPermissions Permissions;
@@ -168,17 +166,6 @@ namespace Barotrauma.Networking
client.kickVoters.RemoveAll(voter => !connectedClients.Contains(voter));
}
}
public void CancelTransfer()
{
if (FileStreamSender == null) return;
FileStreamSender.CancelTransfer();
FileStreamSender.Dispose();
FileStreamSender = null;
}
}
}

View File

@@ -16,10 +16,7 @@ namespace Barotrauma.Networking
private NetClient client;
private GUIMessageBox reconnectBox;
private FileStreamReceiver fileStreamReceiver;
private Queue<Pair<string, FileTransferMessageType>> requestFileQueue;
private GUIButton endRoundButton;
private GUITickBox endVoteTickBox;
@@ -45,12 +42,7 @@ namespace Barotrauma.Networking
return otherClients;
}
}
public string ActiveFileTransferName
{
get { return (fileStreamReceiver == null || fileStreamReceiver.Status == FileTransferStatus.Finished) ? "" : fileStreamReceiver.FileName; }
}
public GameClient(string newName)
{
endVoteTickBox = new GUITickBox(new Rectangle(GameMain.GraphicsWidth - 170, 20, 20, 20), "End round", Alignment.TopLeft, inGameHUD);
@@ -76,9 +68,7 @@ namespace Barotrauma.Networking
Hull.EditWater = false;
name = newName;
requestFileQueue = new Queue<Pair<string, FileTransferMessageType>>();
characterInfo = new CharacterInfo(Character.HumanConfigFile, name);
characterInfo.Job = null;
@@ -125,8 +115,7 @@ namespace Barotrauma.Networking
netPeer = client;
client.Start();
NetOutgoingMessage outmsg = client.CreateMessage();
outmsg.Write((byte)PacketTypes.Login);
NetOutgoingMessage outmsg = client.CreateMessage();
System.Net.IPEndPoint IPEndPoint = null;
@@ -326,16 +315,14 @@ namespace Barotrauma.Networking
}
else if (gameStarted)
{
new NetworkEvent(NetworkEventType.EntityUpdate, myCharacter.ID, true);
}
}
// Update current time
updateTimer = DateTime.Now + updateInterval;
}
private CoroutineHandle startGameCoroutine;
/// <summary>
/// Check for new incoming messages from server
/// </summary>
@@ -343,14 +330,6 @@ namespace Barotrauma.Networking
{
// Create new incoming message holder
NetIncomingMessage inc;
if (startGameCoroutine != null && CoroutineManager.IsCoroutineRunning(startGameCoroutine)) return;
if (fileStreamReceiver == null && requestFileQueue.Count > 0)
{
var newRequest = requestFileQueue.Dequeue();
RequestFile(newRequest.First, newRequest.Second);
}
while ((inc = client.ReadMessage()) != null)
{
@@ -586,96 +565,7 @@ namespace Barotrauma.Networking
return true;
}
public void RequestFile(string file, FileTransferMessageType fileType)
{
if (fileStreamReceiver!=null)
{
var request = new Pair<string, FileTransferMessageType>()
{
First = file,
Second = fileType
};
requestFileQueue.Enqueue(request);
return;
}
NetOutgoingMessage msg = client.CreateMessage();
msg.Write((byte)PacketTypes.RequestFile);
msg.Write((byte)fileType);
msg.Write(file);
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
fileStreamReceiver = new FileStreamReceiver(client, Path.Combine(Submarine.SavePath, "Downloaded"), fileType, OnFileReceived);
}
private void OnFileReceived(FileStreamReceiver receiver)
{
if (receiver.Status == FileTransferStatus.Error)
{
new GUIMessageBox("Error while receiving file from server", receiver.ErrorMessage, 400, 350);
receiver.DeleteFile();
}
else if (receiver.Status == FileTransferStatus.Finished)
{
new GUIMessageBox("Download finished", "File ''" + receiver.FileName + "'' was downloaded succesfully.");
switch (receiver.FileType)
{
case FileTransferMessageType.Submarine:
Submarine.SavedSubmarines.RemoveAll(s => s.Name + ".sub" == receiver.FileName);
for (int i = 0; i<2; i++)
{
var textBlock = (i == 0) ?
GameMain.NetLobbyScreen.ShuttleList.ListBox.children.Find(c => (c.UserData as Submarine).Name+".sub" == receiver.FileName) :
GameMain.NetLobbyScreen.SubList.children.Find(c => (c.UserData as Submarine).Name+".sub" == receiver.FileName);
if (textBlock == null) continue;
(textBlock as GUITextBlock).TextColor = Color.White;
var newSub = new Submarine(receiver.FilePath);
Submarine.SavedSubmarines.Add(newSub);
textBlock.UserData = newSub;
}
break;
}
}
fileStreamReceiver = null;
}
private void CancelFileTransfer()
{
fileStreamReceiver.DeleteFile();
fileStreamReceiver.Dispose();
fileStreamReceiver = null;
NetOutgoingMessage msg = client.CreateMessage();
msg.Write((byte)PacketTypes.RequestFile);
msg.Write((byte)FileTransferMessageType.Cancel);
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
}
public override void KickPlayer(string kickedName, bool ban)
{
if (!permissions.HasFlag(ClientPermissions.Kick) && !ban) return;
if (!permissions.HasFlag(ClientPermissions.Ban) && ban) return;
NetOutgoingMessage msg = client.CreateMessage();
msg.Write((byte)PacketTypes.KickPlayer);
msg.Write(ban);
msg.Write(kickedName);
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
}
public bool VoteForKick(GUIButton button, object userdata)
{
var votedClient = otherClients.Find(c => c.Character == userdata);
@@ -695,7 +585,7 @@ namespace Barotrauma.Networking
public void Vote(VoteType voteType, object userData)
{
NetOutgoingMessage msg = client.CreateMessage();
msg.Write((byte)PacketTypes.Vote);
msg.Write((byte)voteType);
switch (voteType)
@@ -723,7 +613,7 @@ namespace Barotrauma.Networking
public bool SpectateClicked(GUIButton button, object userData)
{
NetOutgoingMessage msg = client.CreateMessage();
msg.Write((byte)PacketTypes.SpectateRequest);
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
@@ -754,7 +644,6 @@ namespace Barotrauma.Networking
if (characterInfo == null) return;
NetOutgoingMessage msg = client.CreateMessage();
msg.Write((byte)PacketTypes.CharacterInfo);
msg.Write(characterInfo.Name);
msg.Write(characterInfo.Gender == Gender.Male);

View File

@@ -351,8 +351,6 @@ namespace Barotrauma.Networking
foreach (Client c in connectedClients)
{
if (c.FileStreamSender != null) UpdateFileTransfer(c, deltaTime);
//c.ReliableChannel.Update(deltaTime);
//slowly reset spam timers
@@ -365,7 +363,7 @@ namespace Barotrauma.Networking
{
try
{
ReadMessage(inc);
}
catch (Exception e)
{
@@ -382,7 +380,6 @@ namespace Barotrauma.Networking
{
if (gameStarted)
{
if (myCharacter != null && !myCharacter.IsDead) new NetworkEvent(NetworkEventType.EntityUpdate, myCharacter.ID, false);
float ignoreDistance = FarseerPhysics.ConvertUnits.ToDisplayUnits(NetConfig.CharacterIgnoreDistance);
@@ -394,7 +391,7 @@ namespace Barotrauma.Networking
c2 => c2.IsNetworkPlayer &&
Vector2.Distance(c2.WorldPosition, c.WorldPosition) < ignoreDistance))
{
new NetworkEvent(NetworkEventType.EntityUpdate, c.ID, false);
}
//todo: take multiple subs into account
@@ -407,8 +404,7 @@ namespace Barotrauma.Networking
if (server.ConnectionsCount > 0)
{
if (sparseUpdateTimer < DateTime.Now) SparseUpdate();
SendNetworkEvents();
}
updateTimer = DateTime.Now + updateInterval;
@@ -444,557 +440,12 @@ namespace Barotrauma.Networking
//if (FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) > NetConfig.CharacterIgnoreDistance) continue;
}
new NetworkEvent(NetworkEventType.ImportantEntityUpdate, c.ID, false);
}
sparseUpdateTimer = DateTime.Now + sparseUpdateInterval;
}
private void ReadMessage(NetIncomingMessage inc)
{
Client sender = connectedClients.Find(x => x.Connection == inc.SenderConnection);
switch (inc.MessageType)
{
case NetIncomingMessageType.ConnectionApproval:
HandleConnectionApproval(inc);
break;
case NetIncomingMessageType.StatusChanged:
Debug.WriteLine(inc.SenderConnection + " status changed. " + (NetConnectionStatus)inc.SenderConnection.Status);
if (inc.SenderConnection.Status == NetConnectionStatus.Disconnected)
{
var connectedClient = connectedClients.Find(c => c.Connection == inc.SenderConnection);
if (connectedClient != null && !disconnectedClients.Contains(connectedClient))
{
connectedClient.deleteDisconnectedTimer = NetConfig.DeleteDisconnectedTime;
disconnectedClients.Add(connectedClient);
}
DisconnectClient(inc.SenderConnection,
connectedClient != null ? connectedClient.name + " has disconnected" : "");
}
break;
case NetIncomingMessageType.Data:
byte packetType = inc.ReadByte();
if (sender == null)
{
var authUser = unauthenticatedClients.Find(c => c.Connection == inc.SenderConnection);
if (authUser == null)
{
unauthenticatedClients.Remove(authUser);
inc.SenderConnection.Disconnect("Disconnected");
}
else
{
CheckAuthentication(inc);
}
return;
}
switch (packetType)
{
case (byte)PacketTypes.NetworkEvent:
if (!gameStarted) break;
NetworkEvent.ReadMessage(inc, true);
break;
case (byte)PacketTypes.Chatmessage:
ReadChatMessage(inc);
break;
case (byte)PacketTypes.PlayerLeft:
DisconnectClient(inc.SenderConnection);
break;
case (byte)PacketTypes.StartGame:
sender.ReadyToStart = true;
break;
case (byte)PacketTypes.EndGame:
if (!sender.HasPermission(ClientPermissions.EndRound))
{
Log(sender.name+" attempted to end the round (insufficient permissions)", Color.Red);
}
else
{
Log("Round ended by " + sender.name, Color.Red);
EndGame();
}
break;
case (byte)PacketTypes.KickPlayer:
bool ban = inc.ReadBoolean();
string kickedName = inc.ReadString();
var kickedClient = connectedClients.Find(c => c.name.ToLowerInvariant() == kickedName.ToLowerInvariant());
if (kickedClient == null || kickedClient == sender) return;
if (ban && !sender.HasPermission(ClientPermissions.Ban))
{
Log(sender.name + " attempted to ban " + kickedClient.name + " (insufficient permissions)", Color.Red);
}
else if (!sender.HasPermission(ClientPermissions.Kick))
{
Log(sender.name + " attempted to kick " + kickedClient.name + " (insufficient permissions)", Color.Red);
}
else
{
KickClient(kickedClient, ban);
}
break;
case (byte)PacketTypes.CharacterInfo:
ReadCharacterData(inc);
break;
case (byte)PacketTypes.RequestFile:
if (!AllowFileTransfers)
{
SendCancelTransferMessage(sender, "File transfers have been disabled by the server.");
break;
}
byte fileType = inc.ReadByte();
string fileName = fileType == (byte)FileTransferMessageType.Cancel ? "" : inc.ReadString();
switch (fileType)
{
case (byte)FileTransferMessageType.Submarine:
var requestedSubmarine = Submarine.SavedSubmarines.Find(s => s.Name == fileName);
if (requestedSubmarine==null)
{
//todo: ei voi ladata
}
else
{
if (sender.FileStreamSender != null) sender.FileStreamSender.CancelTransfer();
var fileStreamSender = FileStreamSender.Create(sender.Connection, requestedSubmarine.FilePath, FileTransferMessageType.Submarine);
if (fileStreamSender != null) sender.FileStreamSender = fileStreamSender;
}
break;
case (byte)FileTransferMessageType.Cancel:
if (sender.FileStreamSender != null)
{
sender.FileStreamSender.CancelTransfer();
}
break;
default:
DebugConsole.ThrowError("Unknown file type was requested ("+fileType+")");
break;
}
break;
case (byte)PacketTypes.ResendRequest:
break;
case (byte)PacketTypes.LatestMessageID:
break;
case (byte)PacketTypes.Vote:
Voting.RegisterVote(inc, connectedClients);
if (Voting.AllowEndVoting && EndVoteMax > 0 &&
((float)EndVoteCount / (float)EndVoteMax) >= EndVoteRequiredRatio)
{
Log("Ending round by votes (" + EndVoteCount + "/" + (EndVoteMax - EndVoteCount) + ")", Color.Cyan);
EndGame();
}
break;
case (byte)PacketTypes.RequestNetLobbyUpdate:
UpdateNetLobby(null, null);
UpdateVoteStatus();
break;
case (byte)PacketTypes.SpectateRequest:
if (gameStarted && AllowSpectating)
{
var startMessage = CreateStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset);
server.SendMessage(startMessage, inc.SenderConnection, NetDeliveryMethod.ReliableOrdered);
CoroutineManager.StartCoroutine(SyncSpectator(sender));
}
break;
}
break;
case NetIncomingMessageType.WarningMessage:
Debug.WriteLine(inc.ReadString());
break;
}
}
private void SendMessage(NetOutgoingMessage msg, NetDeliveryMethod deliveryMethod, NetConnection excludedConnection = null)
{
List<NetConnection> recipients = new List<NetConnection>();
foreach (Client client in connectedClients)
{
if (client.Connection != excludedConnection) recipients.Add(client.Connection);
}
if (recipients.Count == 0) return;
SendMessage(msg, deliveryMethod, recipients);
}
private void SendMessage(NetOutgoingMessage msg, NetDeliveryMethod deliveryMethod, List<NetConnection> recipients)
{
if (recipients == null) recipients = connectedClients.Select(c => c.Connection).ToList();
if (recipients.Count == 0) return;
server.SendMessage(msg, recipients, deliveryMethod, 0);
}
private void SendNetworkEvents(List<Client> recipients = null)
{
if (NetworkEvent.Events.Count == 0) return;
if (recipients == null)
{
recipients = connectedClients.FindAll(c => c.inGame);
}
if (recipients.Count == 0) return;
foreach (Client c in recipients)
{
var message = ComposeNetworkEventMessage(NetworkEventDeliveryMethod.ReliableLidgren, c.Connection);
if (message!=null)
{
server.SendMessage(message, c.Connection, NetDeliveryMethod.ReliableUnordered);
}
message = ComposeNetworkEventMessage(NetworkEventDeliveryMethod.Unreliable, c.Connection);
if (message != null)
{
server.SendMessage(message, c.Connection, NetDeliveryMethod.Unreliable, 0);
}
}
NetworkEvent.Events.Clear();
}
private IEnumerable<object> SyncSpectator(Client sender)
{
yield return new WaitForSeconds(3.0f);
foreach (Item item in Item.Remover.removedItems)
{
Item.Spawner.spawnItems.Remove(item);
}
SendItemRemoveMessage(Item.Remover.removedItems, new List<NetConnection>() { sender.Connection });
SendItemSpawnMessage(Item.Spawner.spawnItems, new List<NetConnection>() { sender.Connection });
yield return new WaitForSeconds(1.0f);
//save all the current events to a list and clear them
var existingEvents = new List<NetworkEvent>(NetworkEvent.Events);
NetworkEvent.Events.Clear();
foreach (Hull hull in Hull.hullList)
{
if (!hull.FireSources.Any() && hull.Volume < 0.01f) continue;
new NetworkEvent(NetworkEventType.ImportantEntityUpdate, hull.ID, false);
}
foreach (Character c in Character.CharacterList)
{
new NetworkEvent(NetworkEventType.EntityUpdate, c.ID, false);
if (c.Inventory != null) new NetworkEvent(NetworkEventType.InventoryUpdate, c.ID, false);
if (c.IsDead) new NetworkEvent(NetworkEventType.KillCharacter, c.ID, false);
}
foreach (Structure wall in Structure.WallList)
{
bool takenDamage = false;
for (int i = 0; i<wall.SectionCount; i++)
{
if (wall.SectionDamage(i) < wall.Health)
{
takenDamage = true;
break;
}
}
if (takenDamage) new NetworkEvent(NetworkEventType.ImportantEntityUpdate, wall.ID, false);
}
foreach (Item item in Item.ItemList)
{
for (int i = 0; i < item.components.Count; i++)
{
if (!item.components[i].NetworkUpdateSent) continue;
item.NewComponentEvent(item.components[i], false, true);
}
if (item.body == null || !item.body.Enabled || item.ParentInventory!=null) continue;
new NetworkEvent(NetworkEventType.DropItem, item.ID, false);
}
List<NetworkEvent> syncMessages = new List<NetworkEvent>(NetworkEvent.Events);
while (syncMessages.Any())
{
//put 5 events in the message and send them to the spectator
NetworkEvent.Events = syncMessages.GetRange(0, Math.Min(syncMessages.Count, 5));
SendNetworkEvents(new List<Client>() { sender });
syncMessages.RemoveRange(0, Math.Min(syncMessages.Count, 5));
//restore "normal" events
NetworkEvent.Events = existingEvents;
yield return new WaitForSeconds(0.1f);
//save "normal" events again
existingEvents = new List<NetworkEvent>(NetworkEvent.Events);
}
yield return new WaitForSeconds(0.1f);
SendRespawnManagerMsg(null, null, new List<NetConnection>() { sender.Connection });
yield return new WaitForSeconds(0.1f);
sender.inGame = true;
yield return CoroutineStatus.Success;
}
public bool StartGameClicked(GUIButton button, object obj)
{
Submarine selectedSub = null;
Submarine selectedShuttle = GameMain.NetLobbyScreen.SelectedShuttle;
if (Voting.AllowSubVoting)
{
selectedSub = Voting.HighestVoted<Submarine>(VoteType.Sub, connectedClients);
if (selectedSub == null) selectedSub = GameMain.NetLobbyScreen.SelectedSub;
}
else
{
selectedSub = GameMain.NetLobbyScreen.SelectedSub;
}
if (selectedSub == null)
{
GameMain.NetLobbyScreen.SubList.Flash();
return false;
}
if (selectedShuttle == null)
{
GameMain.NetLobbyScreen.ShuttleList.Flash();
return false;
}
GameModePreset selectedMode = Voting.HighestVoted<GameModePreset>(VoteType.Mode, connectedClients);
if (selectedMode == null) selectedMode = GameMain.NetLobbyScreen.SelectedMode;
if (selectedMode==null)
{
GameMain.NetLobbyScreen.ModeList.Flash();
return false;
}
CoroutineManager.StartCoroutine(WaitForPlayersReady(selectedSub, selectedShuttle, selectedMode), "WaitForPlayersReady");
return true;
}
private IEnumerable<object> WaitForPlayersReady(Submarine selectedSub, Submarine selectedShuttle, GameModePreset selectedMode)
{
GameMain.NetLobbyScreen.StartButton.Enabled = false;
NetOutgoingMessage msg = server.CreateMessage();
msg.Write((byte)PacketTypes.CanStartGame);
msg.Write(selectedSub.Name);
msg.Write(selectedSub.MD5Hash.Hash);
msg.Write(selectedShuttle.Name);
msg.Write(selectedShuttle.MD5Hash.Hash);
SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
connectedClients.ForEach(c => c.ReadyToStart = false);
float waitForResponseTimer = 5.0f;
while (connectedClients.Any(c => !c.ReadyToStart) && waitForResponseTimer > 0.0f)
{
waitForResponseTimer -= CoroutineManager.UnscaledDeltaTime;
yield return CoroutineStatus.Running;
}
float fileTransferTimeOut = 60.0f;
while (connectedClients.Any(c => c.FileStreamSender != null && c.FileStreamSender.FilePath == selectedSub.FilePath) && fileTransferTimeOut>0.0f)
{
fileTransferTimeOut -= CoroutineManager.UnscaledDeltaTime;
if (GUIMessageBox.MessageBoxes.Count==0)
{
var messageBox = new GUIMessageBox("File transfer in progress",
"The round will be started after the submarine file has been sent to all players.", new string[] {"Cancel transfer"}, 400, 400);
messageBox.Buttons[0].UserData = connectedClients.Find(c => c.FileStreamSender != null && c.FileStreamSender.FilePath == selectedSub.FilePath);
messageBox.Buttons[0].OnClicked = (button, obj) =>
{
(button.UserData as Client).CancelTransfer();
return true;
};
}
}
GameMain.ShowLoading(StartGame(selectedSub, selectedShuttle, selectedMode), false);
yield return CoroutineStatus.Success;
}
private IEnumerable<object> StartGame(Submarine selectedSub, Submarine selectedShuttle, GameModePreset selectedMode)
{
Item.Spawner.Clear();
Item.Remover.Clear();
GameMain.NetLobbyScreen.StartButton.Enabled = false;
GUIMessageBox.CloseAll();
AssignJobs(connectedClients);
roundStartSeed = DateTime.Now.Millisecond;
Rand.SetSyncedSeed(roundStartSeed);
GameMain.GameSession = new GameSession(selectedSub, "", selectedMode, Mission.MissionTypes[GameMain.NetLobbyScreen.MissionTypeIndex]);
GameMain.GameSession.StartShift(GameMain.NetLobbyScreen.LevelSeed);
GameServer.Log("Starting a new round...", Color.Cyan);
GameServer.Log("Submarine: " + selectedSub.Name, Color.Cyan);
GameServer.Log("Game mode: " + selectedMode.Name, Color.Cyan);
GameServer.Log("Level seed: " + GameMain.NetLobbyScreen.LevelSeed, Color.Cyan);
if (AllowRespawn) respawnManager = new RespawnManager(this, selectedShuttle);
yield return CoroutineStatus.Running;
List<CharacterInfo> characterInfos = new List<CharacterInfo>();
foreach (Client client in connectedClients)
{
client.inGame = true;
if (client.characterInfo == null)
{
client.characterInfo = new CharacterInfo(Character.HumanConfigFile, client.name);
}
characterInfos.Add(client.characterInfo);
client.characterInfo.Job = new Job(client.assignedJob);
}
if (characterInfo != null)
{
characterInfo.Job = new Job(GameMain.NetLobbyScreen.JobPreferences[0]);
characterInfos.Add(characterInfo);
}
WayPoint[] assignedWayPoints = WayPoint.SelectCrewSpawnPoints(characterInfos, Submarine.MainSub);
for (int i = 0; i < connectedClients.Count; i++)
{
connectedClients[i].Character = Character.Create(
connectedClients[i].characterInfo, assignedWayPoints[i].WorldPosition, true, false);
connectedClients[i].Character.GiveJobItems(assignedWayPoints[i]);
GameMain.GameSession.CrewManager.characters.Add(connectedClients[i].Character);
}
if (characterInfo != null)
{
myCharacter = Character.Create(characterInfo, assignedWayPoints[assignedWayPoints.Length - 1].WorldPosition, false, false);
Character.Controlled = myCharacter;
myCharacter.GiveJobItems(assignedWayPoints[assignedWayPoints.Length - 1]);
GameMain.GameSession.CrewManager.characters.Add(myCharacter);
}
var startMessage = CreateStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset);
SendMessage(startMessage, NetDeliveryMethod.ReliableOrdered);
//SendItemSpawnMessage(allItems, inventories);
yield return CoroutineStatus.Running;
UpdateCrewFrame();
if (TraitorsEnabled == YesNoMaybe.Yes ||
(TraitorsEnabled == YesNoMaybe.Maybe && Rand.Range(0.0f, 1.0f) < 0.5f))
{
TraitorManager = new TraitorManager(this);
}
else
{
TraitorManager = null;
}
//give some time for the clients to load the map
yield return new WaitForSeconds(2.0f);
gameStarted = true;
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
GameMain.GameScreen.Select();
if (myCharacter == null)
{
AddChatMessage("Press TAB to chat. Use ''d;'' to talk to dead players and spectators, "
+ "and ''player name;'' to only send the message to a specific player.", ChatMessageType.Server);
}
else
{
AddChatMessage("Press TAB to chat. Use ''r;'' to talk through the radio.", ChatMessageType.Server);
}
GameMain.NetLobbyScreen.StartButton.Enabled = true;
yield return CoroutineStatus.Success;
}
private NetOutgoingMessage CreateStartMessage(int seed, Submarine selectedSub, GameModePreset selectedMode)
{
NetOutgoingMessage msg = server.CreateMessage();
msg.Write((byte)PacketTypes.StartGame);
msg.Write(seed);
msg.Write(GameMain.NetLobbyScreen.LevelSeed);
msg.Write((byte)GameMain.NetLobbyScreen.MissionTypeIndex);
msg.Write(selectedSub.Name);
msg.Write(selectedSub.MD5Hash.Hash);
msg.Write(GameMain.NetLobbyScreen.SelectedShuttle.Name);
msg.Write(GameMain.NetLobbyScreen.SelectedShuttle.MD5Hash.Hash);
msg.Write(selectedMode.Name);
msg.Write(AllowRespawn);
//msg.Write(GameMain.NetLobbyScreen.GameDuration.TotalMinutes);
var characters = Character.CharacterList.FindAll(c => !(c is AICharacter) || c.SpawnedMidRound);
msg.Write((byte)characters.Count);
foreach (Character c in characters)
{
WriteCharacterData(msg, c.Name, c);
}
return msg;
}
public void EndGame()
{
if (!gameStarted) return;
@@ -1029,114 +480,14 @@ namespace Barotrauma.Networking
if (connectedClients.Count > 0)
{
NetOutgoingMessage msg = server.CreateMessage();
msg.Write((byte)PacketTypes.EndGame);
msg.Write(endMessage);
if (server.ConnectionsCount > 0)
{
server.SendMessage(msg, server.Connections, NetDeliveryMethod.ReliableOrdered, 0);
}
foreach (Client client in connectedClients)
{
client.Character = null;
client.inGame = false;
}
}
CoroutineManager.StartCoroutine(EndCinematic());
}
public IEnumerable<object> EndCinematic()
{
float endPreviewLength = 10.0f;
var cinematic = new TransitionCinematic(Submarine.MainSub, GameMain.GameScreen.Cam, endPreviewLength);
float secondsLeft = endPreviewLength;
do
{
secondsLeft -= CoroutineManager.UnscaledDeltaTime;
yield return CoroutineStatus.Running;
} while (secondsLeft > 0.0f);
Submarine.Unload();
GameMain.NetLobbyScreen.Select();
yield return CoroutineStatus.Success;
}
public void SendRespawnManagerMsg(List<Character> spawnedCharacters = null, List<Item> spawnedItems = null, List<NetConnection> recipients = null)
{
if (respawnManager == null) return;
NetOutgoingMessage msg = server.CreateMessage();
msg.Write((byte)PacketTypes.Respawn);
respawnManager.WriteNetworkEvent(msg, spawnedCharacters, spawnedItems);
SendMessage(msg, NetDeliveryMethod.ReliableUnordered, recipients);
}
private void DisconnectClient(NetConnection senderConnection, string msg = "", string targetmsg = "")
{
Client client = connectedClients.Find(x => x.Connection == senderConnection);
if (client == null) return;
DisconnectClient(client, msg, targetmsg);
}
private void DisconnectClient(Client client, string msg = "", string targetmsg = "")
{
if (client == null) return;
if (gameStarted && client.Character != null)
{
client.Character.ClearInputs();
client.Character.Kill(CauseOfDeath.Disconnected, true);
}
client.Character = null;
client.inGame = false;
if (string.IsNullOrWhiteSpace(msg)) msg = client.name + " has left the server";
if (string.IsNullOrWhiteSpace(targetmsg)) targetmsg = "You have left the server";
Log(msg, ChatMessage.MessageColor[(int)ChatMessageType.Server]);
client.Connection.Disconnect(targetmsg);
//notify other players about the disconnected client
NetOutgoingMessage outmsg = server.CreateMessage();
outmsg.Write((byte)PacketTypes.PlayerLeft);
outmsg.Write(client.ID);
outmsg.Write(msg);
GameMain.NetLobbyScreen.RemovePlayer(client.name);
if (server.Connections.Count > 0)
{
server.SendMessage(outmsg, server.Connections, NetDeliveryMethod.ReliableUnordered, 0);
}
connectedClients.Remove(client);
if (client.FileStreamSender != null)
{
client.FileStreamSender.Dispose();
client.FileStreamSender = null;
}
AddChatMessage(msg, ChatMessageType.Server);
UpdateCrewFrame();
refreshMasterTimer = DateTime.Now;
}
private void UpdateCrewFrame()
{
List<Character> crew = new List<Character>();
@@ -1152,92 +503,7 @@ namespace Barotrauma.Networking
//if (GameMain.GameSession!=null) GameMain.GameSession.CrewManager.CreateCrewFrame(crew);
}
public override void KickPlayer(string playerName, bool ban)
{
playerName = playerName.ToLowerInvariant();
Client client = connectedClients.Find(c =>
c.name.ToLowerInvariant() == playerName ||
(c.Character != null && c.Character.Name.ToLowerInvariant() == playerName));
KickClient(client, ban);
}
public void KickClient(Client client, bool ban = false)
{
if (client == null) return;
if (ban)
{
DisconnectClient(client, client.name + " has been banned from the server", "You have been banned from the server");
banList.BanPlayer(client.name, client.Connection.RemoteEndPoint.Address.ToString());
}
else
{
DisconnectClient(client, client.name + " has been kicked from the server", "You have been kicked from the server");
}
}
private void UpdateFileTransfer(Client client, float deltaTime)
{
if (client.FileStreamSender == null) return;
var clientNameBox = GameMain.NetLobbyScreen.PlayerList.FindChild(client.name);
var clientInfo = clientNameBox.FindChild(client.FileStreamSender);
if (clientInfo == null)
{
clientNameBox.ClearChildren();
clientInfo = new GUIFrame(new Rectangle(0, 0, 180, 0), Color.Transparent, Alignment.TopRight, null, clientNameBox);
clientInfo.UserData = client.FileStreamSender;
new GUIProgressBar(new Rectangle(0, 4, 160, clientInfo.Rect.Height - 8), Color.Green, GUI.Style, 0.0f, Alignment.Left, clientInfo).IsHorizontal = true;
new GUITextBlock(new Rectangle(0, 2, 160, 0), "", GUI.Style, Alignment.TopLeft, Alignment.Left | Alignment.CenterY, clientInfo, true, GUI.SmallFont);
var cancelButton = new GUIButton(new Rectangle(20, 0, 14, 0), "X", Alignment.Right, GUI.Style, clientInfo);
cancelButton.OnClicked = (GUIButton button, object userdata) =>
{
(cancelButton.Parent.UserData as FileStreamSender).CancelTransfer();
return true;
};
}
else
{
var progressBar = clientInfo.GetChild<GUIProgressBar>();
progressBar.BarSize = client.FileStreamSender.Progress;
var progressText = clientInfo.GetChild<GUITextBlock>();
progressText.Text = client.FileStreamSender.FileName + " " +
MathUtils.GetBytesReadable(client.FileStreamSender.Sent) + " / " + MathUtils.GetBytesReadable(client.FileStreamSender.FileSize);
}
client.FileStreamSender.Update(deltaTime);
if (client.FileStreamSender.Status != FileTransferStatus.Sending &&
client.FileStreamSender.Status != FileTransferStatus.NotStarted)
{
if (client.FileStreamSender.Status == FileTransferStatus.Canceled)
{
SendCancelTransferMessage(client, "File transfer was canceled by the server.");
}
clientNameBox.RemoveChild(clientInfo);
client.FileStreamSender.Dispose();
client.FileStreamSender = null;
}
}
private void SendCancelTransferMessage(Client client, string message)
{
var outmsg = server.CreateMessage();
outmsg.Write((byte)PacketTypes.RequestFile);
outmsg.Write(false);
outmsg.Write(message);
server.SendMessage(outmsg, client.Connection, NetDeliveryMethod.ReliableUnordered);
}
public void NewTraitor(Character traitor, Character target)
{
Log(traitor.Name + " is the traitor and the target is " + target.Name, Color.Cyan);
@@ -1249,14 +515,7 @@ namespace Barotrauma.Networking
traitorClient = c;
break;
}
NetOutgoingMessage msg = server.CreateMessage();
msg.Write((byte)PacketTypes.Traitor);
msg.Write(target.Info.Name);
if (server.Connections.Count > 0)
{
server.SendMessage(msg, traitorClient.Connection, NetDeliveryMethod.ReliableUnordered, 0);
}
}
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)

View File

@@ -27,250 +27,6 @@ namespace Barotrauma.Networking
partial class GameServer : NetworkMember, IPropertyObject
{
List<UnauthenticatedClient> unauthenticatedClients = new List<UnauthenticatedClient>();
private void HandleConnectionApproval(NetIncomingMessage inc)
{
if ((PacketTypes)inc.ReadByte() != PacketTypes.Login) return;
if (banList.IsBanned(inc.SenderEndPoint.Address.ToString()))
{
inc.SenderConnection.Deny("You have been banned from the server");
DebugConsole.NewMessage("Banned player tried to join the server", Color.Red);
return;
}
if (connectedClients.Any(c => c.Connection == inc.SenderConnection))
{
inc.SenderConnection.Deny("Connection error - already joined");
return;
}
int nonce = CryptoRandom.Instance.Next();
var msg = server.CreateMessage();
msg.Write(nonce);
unauthenticatedClients.Add(new UnauthenticatedClient(inc.SenderConnection, nonce));
inc.SenderConnection.Approve(msg);
}
private void CheckAuthentication(NetIncomingMessage inc)
{
var unauthenticatedClient = unauthenticatedClients.Find(uc => uc.Connection == inc.SenderConnection);
if (unauthenticatedClient != null)
{
unauthenticatedClients.Remove(unauthenticatedClient);
string saltedPw = password;
saltedPw = saltedPw + Convert.ToString(unauthenticatedClient.Nonce);
saltedPw = Encoding.UTF8.GetString(NetUtility.ComputeSHAHash(Encoding.UTF8.GetBytes(saltedPw)));
NetEncryption algo = new NetXtea(server, saltedPw);
inc.Decrypt(algo);
string rdPw = inc.ReadString();
if (rdPw != saltedPw)
{
inc.SenderConnection.Disconnect("Wrong password!");
return;
}
}
else
{
inc.SenderConnection.Disconnect("Authentication failed");
return;
}
if (ConnectedClients.Count>=config.MaximumConnections)
{
inc.SenderConnection.Disconnect("Server full");
return;
}
DebugConsole.NewMessage("New player has joined the server", Color.White);
byte userID;
string version = "", packageName = "", packageHash = "", name = "";
try
{
userID = inc.ReadByte();
version = inc.ReadString();
packageName = inc.ReadString();
packageHash = inc.ReadString();
name = Client.SanitizeName(inc.ReadString());
}
catch
{
inc.SenderConnection.Disconnect("Connection error - server failed to read your ConnectionApproval message");
DebugConsole.NewMessage("Connection error - server failed to read the ConnectionApproval message", Color.Red);
return;
}
#if !DEBUG
if (string.IsNullOrWhiteSpace(name))
{
inc.SenderConnection.Disconnect("Invalid username");
DebugConsole.NewMessage(name + " couldn't join the server (name empty)", Color.Red);
return;
}
else if (!Client.IsValidName(name))
{
inc.SenderConnection.Disconnect("Username contains illegal symbols");
DebugConsole.NewMessage(name + " couldn't join the server (username contains illegal symbols)", Color.Red);
return;
}
else if (version != GameMain.Version.ToString())
{
inc.SenderConnection.Disconnect("Version " + GameMain.Version + " required to connect to the server (Your version: " + version + ")");
DebugConsole.NewMessage(name + " couldn't join the server (wrong game version)", Color.Red);
return;
}
else if (packageName != GameMain.SelectedPackage.Name)
{
inc.SenderConnection.Disconnect("Your content package (" + packageName + ") doesn't match the server's version (" + GameMain.SelectedPackage.Name + ")");
DebugConsole.NewMessage(name + " couldn't join the server (wrong content package name)", Color.Red);
return;
}
else if (packageHash != GameMain.SelectedPackage.MD5hash.Hash)
{
inc.SenderConnection.Disconnect("Your content package (MD5: " + packageHash + ") doesn't match the server's version (MD5: " + GameMain.SelectedPackage.MD5hash.Hash + ")");
DebugConsole.NewMessage(name + " couldn't join the server (wrong content package hash)", Color.Red);
return;
}
else if (connectedClients.Any(c => c.name.ToLower() == name.ToLower() && c.Connection != inc.SenderConnection))
{
inc.SenderConnection.Disconnect("The name ''" + name + "'' is already in use. Please choose another name.");
DebugConsole.NewMessage(name + " couldn't join the server (name already in use)", Color.Red);
return;
}
#endif
//existing user re-joining
if (userID > 0)
{
Client existingClient = connectedClients.Find(c =>
c.ID == userID &&
c.Connection == inc.SenderConnection);
if (existingClient == null)
{
existingClient = disconnectedClients.Find(c =>
c.ID == userID &&
c.Connection == inc.SenderConnection);
if (existingClient != null)
{
disconnectedClients.Remove(existingClient);
connectedClients.Add(existingClient);
UpdateCrewFrame();
}
}
if (existingClient != null)
{
existingClient.Connection = inc.SenderConnection;
LogClientIn(inc);
return;
}
}
userID = 1;
while (connectedClients.Any(c => c.ID == userID))
{
userID++;
}
Client newClient = new Client(server, name, userID);
newClient.Connection = inc.SenderConnection;
newClient.version = version;
var savedPermissions = clientPermissions.Find(cp => cp.IP == newClient.Connection.RemoteEndPoint.Address.ToString());
if (savedPermissions != null)
{
newClient.SetPermissions(savedPermissions.Permissions);
}
connectedClients.Add(newClient);
UpdateCrewFrame();
LogClientIn(inc);
refreshMasterTimer = DateTime.Now;
}
private void LogClientIn(NetIncomingMessage inc)
{
Client sender = connectedClients.Find(x => x.Connection == inc.SenderConnection);
if (sender == null) return;
if (sender.version != GameMain.Version.ToString())
{
DisconnectClient(sender, sender.name + " was unable to connect to the server (nonmatching game version)",
"Version " + GameMain.Version + " required to connect to the server (Your version: " + sender.version + ")");
}
else if (connectedClients.Find(x => x.name == sender.name && x != sender) != null)
{
DisconnectClient(sender, sender.name + " was unable to connect to the server (name already in use)",
"The name ''" + sender.name + "'' is already in use. Please choose another name.");
}
else
{
//AssignJobs();
GameMain.NetLobbyScreen.RemovePlayer(sender.name);
GameMain.NetLobbyScreen.AddPlayer(sender.name);
// Notify the client that they have logged in
var outmsg = server.CreateMessage();
outmsg.Write((byte)PacketTypes.LoggedIn);
outmsg.Write(sender.ID);
outmsg.Write((int)sender.Permissions);
outmsg.Write(gameStarted);
outmsg.Write(gameStarted && sender.Character != null && !sender.Character.IsDead);
outmsg.Write(AllowSpectating);
//notify the client about other clients already logged in
outmsg.Write((byte)((characterInfo == null) ? connectedClients.Count - 1 : connectedClients.Count));
foreach (Client c in connectedClients)
{
if (c.Connection == inc.SenderConnection) continue;
outmsg.Write(c.name);
outmsg.Write(c.ID);
}
if (characterInfo != null)
{
outmsg.Write(characterInfo.Name);
outmsg.Write((byte)0);
}
var subs = GameMain.NetLobbyScreen.GetSubList();
outmsg.Write((byte)subs.Count);
foreach (Submarine sub in subs)
{
outmsg.Write(sub.Name);
outmsg.Write(sub.MD5Hash.Hash);
}
server.SendMessage(outmsg, inc.SenderConnection, NetDeliveryMethod.ReliableUnordered, 0);
//notify other clients about the new client
outmsg = server.CreateMessage();
outmsg.Write((byte)PacketTypes.PlayerJoined);
outmsg.Write(sender.name);
outmsg.Write(sender.ID);
//send the message to everyone except the client who just logged in
SendMessage(outmsg, NetDeliveryMethod.ReliableUnordered, inc.SenderConnection);
AddChatMessage(sender.name + " has joined the server", ChatMessageType.Server);
}
}
}
}

View File

@@ -214,8 +214,6 @@ namespace Barotrauma.Networking
doc.Root.SetAttributeValue("SubSelection", subSelectionMode.ToString());
doc.Root.SetAttributeValue("ModeSelection", modeSelectionMode.ToString());
doc.Root.SetAttributeValue("MaxFileTransferDuration", FileStreamSender.MaxTransferDuration.TotalSeconds);
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
@@ -250,8 +248,6 @@ namespace Barotrauma.Networking
Enum.TryParse<SelectionMode>(ToolBox.GetAttributeString(doc.Root, "ModeSelection", "Manual"), out modeSelectionMode);
Voting.AllowModeVoting = modeSelectionMode == SelectionMode.Vote;
FileStreamSender.MaxTransferDuration = new TimeSpan(0,0,ToolBox.GetAttributeInt(doc.Root, "MaxFileTransferDuration", 150));
showLogButton.Visible = SaveServerLogs;
}

View File

@@ -9,45 +9,6 @@ using Barotrauma.Items.Components;
namespace Barotrauma.Networking
{
enum PacketTypes : byte
{
Unknown,
Login, LoggedIn,
PlayerJoined, PlayerLeft,
KickPlayer,
Permissions,
RequestNetLobbyUpdate,
StartGame, EndGame, CanStartGame,
NewItem, RemoveItem,
NewCharacter,
CharacterInfo,
Chatmessage, UpdateNetLobby,
NetworkEvent,
Traitor,
Vote, VoteStatus,
ResendRequest, ReliableMessage, LatestMessageID,
RequestFile, FileStream,
SpectateRequest,
Respawn
}
enum VoteType
{
Unknown,
@@ -152,65 +113,6 @@ namespace Barotrauma.Networking
Voting = new Voting();
}
protected NetOutgoingMessage ComposeNetworkEventMessage(NetworkEventDeliveryMethod deliveryMethod, NetConnection excludedConnection = null)
{
if (netPeer == null) return null;
var events = NetworkEvent.Events.FindAll(e => e.DeliveryMethod == deliveryMethod);
if (events.Count == 0) return null;
List<byte[]> msgBytes = new List<byte[]>();
foreach (NetworkEvent networkEvent in events)
{
if (excludedConnection != null && networkEvent.SenderConnection == excludedConnection) continue;
NetBuffer tempMessage = new NetBuffer();// server.CreateMessage();
if (!networkEvent.FillData(tempMessage)) continue;
tempMessage.WritePadBits();
tempMessage.Position = 0;
msgBytes.Add(tempMessage.ReadBytes(tempMessage.LengthBytes));
#if DEBUG
string msgType = networkEvent.Type.ToString();
if (networkEvent.Type == NetworkEventType.EntityUpdate)
{
msgType += " (" + Entity.FindEntityByID(networkEvent.ID) + ")";
}
long sentBytes = 0;
if (!messageCount.TryGetValue(msgType, out sentBytes))
{
messageCount.Add(msgType, tempMessage.LengthBytes);
}
else
{
messageCount[msgType] += tempMessage.LengthBytes;
}
#endif
}
if (msgBytes.Count == 0) return null;
NetOutgoingMessage message = netPeer.CreateMessage();
message.Write((byte)PacketTypes.NetworkEvent);
message.Write((float)NetTime.Now);
message.Write((byte)msgBytes.Count);
foreach (byte[] msgData in msgBytes)
{
if (msgData.Length > 255) DebugConsole.ThrowError("Too large networkevent (" + msgData.Length + " bytes)");
message.Write((byte)msgData.Length);
message.Write(msgData);
}
return message;
}
public bool TypingChatMessage(GUITextBox textBox, string text)
{
string tempStr;

View File

@@ -161,7 +161,6 @@ namespace Barotrauma.Networking
if (!CountdownStarted)
{
CountdownStarted = true;
server.SendRespawnManagerMsg();
}
}
else
@@ -209,7 +208,6 @@ namespace Barotrauma.Networking
state = State.Returning;
CountdownStarted = false;
server.SendRespawnManagerMsg();
shuttleReturnTimer = maxTransportTime;
shuttleTransportTimer = maxTransportTime;
}
@@ -275,8 +273,6 @@ namespace Barotrauma.Networking
state = State.Waiting;
respawnTimer = respawnInterval;
CountdownStarted = false;
server.SendRespawnManagerMsg();
}
}
}
@@ -459,103 +455,8 @@ namespace Barotrauma.Networking
character.GiveJobItems(mainSubSpawnPoints[i]);
GameMain.GameSession.CrewManager.characters.Add(character);
}
server.SendRespawnManagerMsg(spawnedCharacters, spawnedItems);
}
public void WriteNetworkEvent(NetOutgoingMessage msg, List<Character> spawnedCharacters, List<Item> spawnedItems)
{
var server = networkMember as GameServer;
msg.WriteRangedInteger(0, Enum.GetNames(typeof(State)).Length, (int)state);
switch (state)
{
case State.Transporting:
msg.Write(maxTransportTime);
if (spawnedCharacters == null)
{
msg.Write((byte)0);
}
else
{
msg.Write((byte)spawnedCharacters.Count);
foreach (Character character in spawnedCharacters)
{
if (character == server.Character)
{
msg.Write((byte)0);
}
else
{
var ownerClient = server.ConnectedClients.Find(cl => cl.Character == character);
msg.Write((byte)ownerClient.ID);
}
server.WriteCharacterData(msg, character.Name, character);
}
}
if (spawnedItems != null) GameMain.Server.SendItemSpawnMessage(spawnedItems);
break;
case State.Waiting:
msg.Write(CountdownStarted);
msg.Write(respawnTimer);
break;
case State.Returning:
//CoroutineManager.StopCoroutines("forcepos");
//CoroutineManager.StartCoroutine(
// ForceShuttleToPos(new Vector2(Level.Loaded.StartPosition.X, Level.Loaded.Size.Y + 1000.0f), 100.0f), "forcepos");
break;
}
}
public void ReadNetworkEvent(NetIncomingMessage inc)
{
var newState = (State)inc.ReadRangedInteger(0, Enum.GetNames(typeof(State)).Length);
switch (newState)
{
case State.Transporting:
maxTransportTime = inc.ReadSingle();
CountdownStarted = false;
var client = networkMember as GameClient;
int clientCount = inc.ReadByte();
//respawning characters -> reset shuttle
if (clientCount > 0) ResetShuttle();
for (int i = 0; i < clientCount; i++)
{
byte clientId = inc.ReadByte();
var character = client.ReadCharacterData(inc);
}
if (state != newState)
{
CoroutineManager.StopCoroutines("forcepos");
CoroutineManager.StartCoroutine(ForceShuttleToPos(Level.Loaded.StartPosition - Vector2.UnitY * Level.ShaftHeight, 100.0f), "forcepos");
}
break;
case State.Waiting:
CountdownStarted = inc.ReadBoolean();
ResetShuttle();
respawnTimer = inc.ReadSingle();
break;
case State.Returning:
CountdownStarted = false;
break;
}
state = newState;
}
}
}