(bf212a41f) v0.9.2.0 pre-release test version
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Lidgren.Network;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -42,6 +43,27 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
private Vector2 spectate_position;
|
||||
public Vector2? SpectatePos
|
||||
{
|
||||
get
|
||||
{
|
||||
if (character == null || character.IsDead)
|
||||
{
|
||||
return spectate_position;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
spectate_position = value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private bool muted;
|
||||
public bool Muted
|
||||
{
|
||||
|
||||
@@ -21,7 +21,8 @@ namespace Barotrauma.Networking
|
||||
ServerLog = 0x100,
|
||||
ManageSettings = 0x200,
|
||||
ManagePermissions = 0x400,
|
||||
All = 0x7ff
|
||||
KarmaImmunity = 0x800,
|
||||
All = 0xFFF
|
||||
}
|
||||
|
||||
class PermissionPreset
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class KarmaManager : ISerializableEntity
|
||||
{
|
||||
public static readonly string ConfigFile = "Data" + Path.DirectorySeparatorChar + "karmasettings.xml";
|
||||
|
||||
public string Name => "KarmaManager";
|
||||
|
||||
public Dictionary<string, SerializableProperty> SerializableProperties { get; private set; }
|
||||
|
||||
[Serialize(0.1f, true)]
|
||||
public float KarmaDecay { get; set; }
|
||||
|
||||
[Serialize(50.0f, true)]
|
||||
public float KarmaDecayThreshold { get; set; }
|
||||
|
||||
[Serialize(0.15f, true)]
|
||||
public float KarmaIncrease { get; set; }
|
||||
|
||||
[Serialize(50.0f, true)]
|
||||
public float KarmaIncreaseThreshold { get; set; }
|
||||
|
||||
[Serialize(0.05f, true)]
|
||||
public float StructureRepairKarmaIncrease { get; set; }
|
||||
[Serialize(0.1f, true)]
|
||||
public float StructureDamageKarmaDecrease { get; set; }
|
||||
[Serialize(30.0f, true)]
|
||||
public float MaxStructureDamageKarmaDecreasePerSecond { get; set; }
|
||||
|
||||
[Serialize(0.03f, true)]
|
||||
public float ItemRepairKarmaIncrease { get; set; }
|
||||
|
||||
[Serialize(0.5f, true)]
|
||||
public float ReactorOverheatKarmaDecrease { get; set; }
|
||||
[Serialize(30.0f, true)]
|
||||
public float ReactorMeltdownKarmaDecrease { get; set; }
|
||||
|
||||
[Serialize(0.1f, true)]
|
||||
public float DamageEnemyKarmaIncrease { get; set; }
|
||||
[Serialize(0.2f, true)]
|
||||
public float HealFriendlyKarmaIncrease { get; set; }
|
||||
[Serialize(0.25f, true)]
|
||||
public float DamageFriendlyKarmaDecrease { get; set; }
|
||||
|
||||
[Serialize(1.0f, true)]
|
||||
public float ExtinguishFireKarmaIncrease { get; set; }
|
||||
|
||||
|
||||
private float allowedWireDisconnectionsPerMinute;
|
||||
[Serialize(5.0f, true)]
|
||||
public float AllowedWireDisconnectionsPerMinute
|
||||
{
|
||||
get { return allowedWireDisconnectionsPerMinute; }
|
||||
set { allowedWireDisconnectionsPerMinute = Math.Max(0.0f, value); }
|
||||
}
|
||||
|
||||
[Serialize(6.0f, true)]
|
||||
public float WireDisconnectionKarmaDecrease { get; set; }
|
||||
|
||||
[Serialize(0.15f, true)]
|
||||
public float SteerSubKarmaIncrease { get; set; }
|
||||
|
||||
[Serialize(15.0f, true)]
|
||||
public float SpamFilterKarmaDecrease { get; set; }
|
||||
|
||||
[Serialize(40.0f, true)]
|
||||
public float HerpesThreshold { get; set; }
|
||||
|
||||
[Serialize(1.0f, true)]
|
||||
public float KickBanThreshold { get; set; }
|
||||
|
||||
[Serialize(10.0f, true)]
|
||||
public float KarmaNotificationInterval { get; set; }
|
||||
|
||||
private readonly AfflictionPrefab herpesAffliction;
|
||||
|
||||
public Dictionary<string, XElement> Presets = new Dictionary<string, XElement>();
|
||||
|
||||
public KarmaManager()
|
||||
{
|
||||
XDocument doc = XMLExtensions.TryLoadXml(ConfigFile);
|
||||
SerializableProperties = SerializableProperty.DeserializeProperties(this, doc?.Root);
|
||||
if (doc?.Root != null)
|
||||
{
|
||||
Presets["custom"] = doc.Root;
|
||||
foreach (XElement subElement in doc.Root.Elements())
|
||||
{
|
||||
string presetName = subElement.GetAttributeString("name", "");
|
||||
Presets[presetName.ToLowerInvariant()] = subElement;
|
||||
}
|
||||
SelectPreset("default");
|
||||
}
|
||||
herpesAffliction = AfflictionPrefab.List.Find(ap => ap.Identifier == "spaceherpes");
|
||||
}
|
||||
|
||||
public void SelectPreset(string presetName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(presetName)) { return; }
|
||||
presetName = presetName.ToLowerInvariant();
|
||||
|
||||
if (Presets.ContainsKey(presetName))
|
||||
{
|
||||
SerializableProperty.DeserializeProperties(this, Presets[presetName]);
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveCustomPreset()
|
||||
{
|
||||
if (Presets.ContainsKey("custom"))
|
||||
{
|
||||
SerializableProperty.SerializeProperties(this, Presets["custom"]);
|
||||
}
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
XDocument doc = new XDocument(new XElement(Name));
|
||||
|
||||
foreach (KeyValuePair<string, XElement> preset in Presets)
|
||||
{
|
||||
doc.Root.Add(preset.Value);
|
||||
}
|
||||
|
||||
XmlWriterSettings settings = new XmlWriterSettings
|
||||
{
|
||||
Indent = true,
|
||||
NewLineOnAttributes = true
|
||||
};
|
||||
|
||||
using (var writer = XmlWriter.Create(ConfigFile, settings))
|
||||
{
|
||||
doc.Save(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,8 @@ namespace Barotrauma.Networking
|
||||
ApplyStatusEffect,
|
||||
ChangeProperty,
|
||||
Control,
|
||||
UpdateSkills
|
||||
UpdateSkills,
|
||||
Combine
|
||||
}
|
||||
|
||||
public readonly Entity Entity;
|
||||
|
||||
@@ -35,7 +35,8 @@ namespace Barotrauma.Networking
|
||||
CHAT_MESSAGE, //also self-explanatory
|
||||
VOTE, //you get the idea
|
||||
CHARACTER_INPUT,
|
||||
ENTITY_STATE
|
||||
ENTITY_STATE,
|
||||
SPECTATING_POS
|
||||
}
|
||||
|
||||
enum ClientNetError
|
||||
@@ -168,7 +169,13 @@ namespace Barotrauma.Networking
|
||||
updateInterval = new TimeSpan(0, 0, 0, 0, MathHelper.Clamp(1000 / serverSettings.TickRate, 1, 500));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public KarmaManager KarmaManager
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
} = new KarmaManager();
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return name; }
|
||||
@@ -214,7 +221,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
var radioComponent = radio.GetComponent<WifiComponent>();
|
||||
if (radioComponent == null) return false;
|
||||
return radioComponent.HasRequiredContainedItems(false);
|
||||
return radioComponent.HasRequiredContainedItems(sender, addMessage: false);
|
||||
}
|
||||
|
||||
public void AddChatMessage(string message, ChatMessageType type, string senderName = "", Character senderCharacter = null)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Barotrauma.Items.Components;
|
||||
using FarseerPhysics;
|
||||
using Lidgren.Network;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -18,10 +17,6 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
private NetworkMember networkMember;
|
||||
|
||||
private State state;
|
||||
|
||||
private Submarine respawnShuttle;
|
||||
private Steering shuttleSteering;
|
||||
private List<Door> shuttleDoors;
|
||||
|
||||
@@ -31,46 +26,40 @@ namespace Barotrauma.Networking
|
||||
|
||||
public bool UsingShuttle
|
||||
{
|
||||
get { return respawnShuttle != null; }
|
||||
get { return RespawnShuttle != null; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// How long until the shuttle is dispatched with respawned characters
|
||||
/// When will the shuttle be dispatched with respawned characters
|
||||
/// </summary>
|
||||
public float RespawnTimer
|
||||
{
|
||||
get { return respawnTimer; }
|
||||
}
|
||||
public DateTime RespawnTime { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// how long until the shuttle starts heading back out of the level
|
||||
/// When will the sub start heading back out of the level
|
||||
/// </summary>
|
||||
public float TransportTimer
|
||||
{
|
||||
get { return shuttleTransportTimer; }
|
||||
}
|
||||
public DateTime ReturnTime { get; private set; }
|
||||
|
||||
public bool CountdownStarted
|
||||
public bool RespawnCountdownStarted
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public State CurrentState
|
||||
public bool ReturnCountdownStarted
|
||||
{
|
||||
get { return state; }
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
private float respawnTimer, shuttleReturnTimer, shuttleTransportTimer;
|
||||
public State CurrentState { get; private set; }
|
||||
|
||||
private DateTime despawnTime;
|
||||
|
||||
private float maxTransportTime;
|
||||
|
||||
private float updateReturnTimer;
|
||||
|
||||
public Submarine RespawnShuttle
|
||||
{
|
||||
get { return respawnShuttle; }
|
||||
}
|
||||
public Submarine RespawnShuttle { get; private set; }
|
||||
|
||||
public RespawnManager(NetworkMember networkMember, Submarine shuttle)
|
||||
: base(shuttle)
|
||||
@@ -79,8 +68,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (shuttle != null)
|
||||
{
|
||||
respawnShuttle = new Submarine(shuttle.FilePath, shuttle.MD5Hash.Hash, true);
|
||||
respawnShuttle.Load(false);
|
||||
RespawnShuttle = new Submarine(shuttle.FilePath, shuttle.MD5Hash.Hash, true);
|
||||
RespawnShuttle.Load(false);
|
||||
|
||||
ResetShuttle();
|
||||
|
||||
@@ -89,7 +78,7 @@ namespace Barotrauma.Networking
|
||||
shuttleDoors = new List<Door>();
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (item.Submarine != respawnShuttle) continue;
|
||||
if (item.Submarine != RespawnShuttle) continue;
|
||||
|
||||
var steering = item.GetComponent<Steering>();
|
||||
if (steering != null) shuttleSteering = steering;
|
||||
@@ -113,13 +102,12 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else
|
||||
{
|
||||
respawnShuttle = null;
|
||||
RespawnShuttle = null;
|
||||
}
|
||||
|
||||
#if SERVER
|
||||
if (networkMember is GameServer server)
|
||||
{
|
||||
respawnTimer = server.ServerSettings.RespawnInterval;
|
||||
maxTransportTime = server.ServerSettings.MaxTransportTime;
|
||||
}
|
||||
#endif
|
||||
@@ -127,15 +115,15 @@ namespace Barotrauma.Networking
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (respawnShuttle == null)
|
||||
if (RespawnShuttle == null)
|
||||
{
|
||||
if (state != State.Waiting)
|
||||
if (CurrentState != State.Waiting)
|
||||
{
|
||||
state = State.Waiting;
|
||||
CurrentState = State.Waiting;
|
||||
}
|
||||
}
|
||||
|
||||
switch (state)
|
||||
switch (CurrentState)
|
||||
{
|
||||
case State.Waiting:
|
||||
UpdateWaiting(deltaTime);
|
||||
@@ -155,32 +143,25 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
//infinite transport time -> shuttle wont return
|
||||
if (maxTransportTime <= 0.0f) return;
|
||||
|
||||
shuttleTransportTimer -= deltaTime;
|
||||
|
||||
UpdateTransportingProjSpecific(deltaTime);
|
||||
}
|
||||
|
||||
partial void UpdateTransportingProjSpecific(float deltaTime);
|
||||
|
||||
public void ForceRespawn()
|
||||
{
|
||||
ResetShuttle();
|
||||
RespawnTime = DateTime.Now;
|
||||
CurrentState = State.Waiting;
|
||||
}
|
||||
|
||||
private void UpdateReturning(float deltaTime)
|
||||
{
|
||||
//if (shuttleReturnTimer == maxTransportTime &&
|
||||
// networkMember.Character != null &&
|
||||
// networkMember.Character.Submarine == respawnShuttle)
|
||||
//{
|
||||
// networkMember.AddChatMessage("The shuttle will automatically return back to the outpost. Please leave the shuttle immediately.", ChatMessageType.Server);
|
||||
//}
|
||||
|
||||
shuttleReturnTimer -= deltaTime;
|
||||
|
||||
updateReturnTimer += deltaTime;
|
||||
|
||||
if (updateReturnTimer > 1.0f)
|
||||
{
|
||||
updateReturnTimer = 0.0f;
|
||||
|
||||
respawnShuttle.PhysicsBody.FarseerBody.IgnoreCollisionWith(Level.Loaded.TopBarrier);
|
||||
RespawnShuttle.PhysicsBody.FarseerBody.IgnoreCollisionWith(Level.Loaded.TopBarrier);
|
||||
|
||||
if (shuttleSteering != null)
|
||||
{
|
||||
@@ -196,41 +177,41 @@ namespace Barotrauma.Networking
|
||||
|
||||
private IEnumerable<object> ForceShuttleToPos(Vector2 position, float speed)
|
||||
{
|
||||
if (respawnShuttle == null)
|
||||
if (RespawnShuttle == null)
|
||||
{
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
respawnShuttle.PhysicsBody.FarseerBody.IgnoreCollisionWith(Level.Loaded.TopBarrier);
|
||||
RespawnShuttle.PhysicsBody.FarseerBody.IgnoreCollisionWith(Level.Loaded.TopBarrier);
|
||||
|
||||
while (Math.Abs(position.Y - respawnShuttle.WorldPosition.Y) > 100.0f)
|
||||
while (Math.Abs(position.Y - RespawnShuttle.WorldPosition.Y) > 100.0f)
|
||||
{
|
||||
Vector2 diff = position - respawnShuttle.WorldPosition;
|
||||
Vector2 diff = position - RespawnShuttle.WorldPosition;
|
||||
if (diff.LengthSquared() > 0.01f)
|
||||
{
|
||||
Vector2 displayVel = Vector2.Normalize(diff) * speed;
|
||||
respawnShuttle.SubBody.Body.LinearVelocity = ConvertUnits.ToSimUnits(displayVel);
|
||||
RespawnShuttle.SubBody.Body.LinearVelocity = ConvertUnits.ToSimUnits(displayVel);
|
||||
}
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
if (respawnShuttle.SubBody == null) yield return CoroutineStatus.Success;
|
||||
if (RespawnShuttle.SubBody == null) yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
respawnShuttle.PhysicsBody.FarseerBody.RestoreCollisionWith(Level.Loaded.TopBarrier);
|
||||
RespawnShuttle.PhysicsBody.FarseerBody.RestoreCollisionWith(Level.Loaded.TopBarrier);
|
||||
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
private void ResetShuttle()
|
||||
{
|
||||
shuttleTransportTimer = maxTransportTime;
|
||||
shuttleReturnTimer = maxTransportTime;
|
||||
ReturnTime = DateTime.Now + new TimeSpan(0, 0, 0, 0, milliseconds: (int)(maxTransportTime * 1000));
|
||||
despawnTime = ReturnTime + new TimeSpan(0, 0, seconds: 30);
|
||||
|
||||
if (respawnShuttle == null) return;
|
||||
if (RespawnShuttle == null) return;
|
||||
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (item.Submarine != respawnShuttle) continue;
|
||||
if (item.Submarine != RespawnShuttle) continue;
|
||||
|
||||
//remove respawn items that have been left in the shuttle
|
||||
if (respawnItems.Contains(item))
|
||||
@@ -251,7 +232,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
foreach (Structure wall in Structure.WallList)
|
||||
{
|
||||
if (wall.Submarine != respawnShuttle) continue;
|
||||
if (wall.Submarine != RespawnShuttle) continue;
|
||||
|
||||
for (int i = 0; i < wall.SectionCount; i++)
|
||||
{
|
||||
@@ -259,12 +240,12 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
var shuttleGaps = Gap.GapList.FindAll(g => g.Submarine == respawnShuttle && g.ConnectedWall != null);
|
||||
var shuttleGaps = Gap.GapList.FindAll(g => g.Submarine == RespawnShuttle && g.ConnectedWall != null);
|
||||
shuttleGaps.ForEach(g => Spawner.AddToRemoveQueue(g));
|
||||
|
||||
foreach (Hull hull in Hull.hullList)
|
||||
{
|
||||
if (hull.Submarine != respawnShuttle) continue;
|
||||
if (hull.Submarine != RespawnShuttle) continue;
|
||||
|
||||
hull.OxygenPercentage = 100.0f;
|
||||
hull.WaterVolume = 0.0f;
|
||||
@@ -272,7 +253,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
if (c.Submarine != respawnShuttle) continue;
|
||||
if (c.Submarine != RespawnShuttle) continue;
|
||||
|
||||
#if CLIENT
|
||||
if (Character.Controlled == c) Character.Controlled = null;
|
||||
@@ -288,15 +269,12 @@ namespace Barotrauma.Networking
|
||||
if (item == null) continue;
|
||||
Spawner.AddToRemoveQueue(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
respawnShuttle.SetPosition(new Vector2(Level.Loaded.StartPosition.X, Level.Loaded.Size.Y + respawnShuttle.Borders.Height));
|
||||
|
||||
respawnShuttle.Velocity = Vector2.Zero;
|
||||
|
||||
respawnShuttle.PhysicsBody.FarseerBody.RestoreCollisionWith(Level.Loaded.TopBarrier);
|
||||
|
||||
RespawnShuttle.SetPosition(new Vector2(Level.Loaded.StartPosition.X, Level.Loaded.Size.Y + RespawnShuttle.Borders.Height));
|
||||
RespawnShuttle.Velocity = Vector2.Zero;
|
||||
RespawnShuttle.PhysicsBody.FarseerBody.RestoreCollisionWith(Level.Loaded.TopBarrier);
|
||||
}
|
||||
|
||||
partial void RespawnCharactersProjSpecific();
|
||||
@@ -305,55 +283,92 @@ namespace Barotrauma.Networking
|
||||
RespawnCharactersProjSpecific();
|
||||
}
|
||||
|
||||
public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null)
|
||||
public Vector2 FindSpawnPos()
|
||||
{
|
||||
msg.WriteRangedInteger(0, Enum.GetNames(typeof(State)).Length, (int)state);
|
||||
if (Level.Loaded == null || Submarine.MainSub == null) { return Vector2.Zero; }
|
||||
|
||||
switch (state)
|
||||
Rectangle dockedBorders = RespawnShuttle.GetDockedBorders();
|
||||
Vector2 diffFromDockedBorders =
|
||||
new Vector2(dockedBorders.Center.X, dockedBorders.Y - dockedBorders.Height / 2)
|
||||
- new Vector2(RespawnShuttle.Borders.Center.X, RespawnShuttle.Borders.Y - RespawnShuttle.Borders.Height / 2);
|
||||
|
||||
int minWidth = Math.Max(dockedBorders.Width, 1000);
|
||||
int minHeight = Math.Max(dockedBorders.Height, 1000);
|
||||
|
||||
List<Level.InterestingPosition> potentialSpawnPositions = new List<Level.InterestingPosition>();
|
||||
foreach (Level.InterestingPosition potentialSpawnPos in Level.Loaded.PositionsOfInterest.Where(p => p.PositionType == Level.PositionType.MainPath))
|
||||
{
|
||||
case State.Transporting:
|
||||
msg.Write(TransportTimer);
|
||||
break;
|
||||
case State.Waiting:
|
||||
msg.Write(CountdownStarted);
|
||||
msg.Write(respawnTimer);
|
||||
break;
|
||||
case State.Returning:
|
||||
break;
|
||||
}
|
||||
bool invalid = false;
|
||||
//make sure the shuttle won't overlap with any ruins
|
||||
foreach (var ruin in Level.Loaded.Ruins)
|
||||
{
|
||||
if (Math.Abs(ruin.Area.Center.X - potentialSpawnPos.Position.X) < (minWidth + ruin.Area.Width) / 2) { invalid = true; break; }
|
||||
if (Math.Abs(ruin.Area.Center.Y - potentialSpawnPos.Position.Y) < (minHeight + ruin.Area.Height) / 2) { invalid = true; break; }
|
||||
}
|
||||
if (invalid) { continue; }
|
||||
|
||||
msg.WritePadBits();
|
||||
}
|
||||
//make sure there aren't any walls too close
|
||||
var tooCloseCells = Level.Loaded.GetTooCloseCells(potentialSpawnPos.Position.ToVector2(), Math.Max(minWidth, minHeight));
|
||||
if (tooCloseCells.Any()) { continue; }
|
||||
|
||||
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
|
||||
{
|
||||
var newState = (State)msg.ReadRangedInteger(0, Enum.GetNames(typeof(State)).Length);
|
||||
//make sure the spawnpoint is far enough from other subs
|
||||
foreach (Submarine sub in Submarine.Loaded)
|
||||
{
|
||||
if (sub == RespawnShuttle || RespawnShuttle.DockedTo.Contains(sub)) { continue; }
|
||||
|
||||
switch (newState)
|
||||
{
|
||||
case State.Transporting:
|
||||
maxTransportTime = msg.ReadSingle();
|
||||
shuttleTransportTimer = maxTransportTime;
|
||||
CountdownStarted = false;
|
||||
|
||||
if (state != newState)
|
||||
float minDist = Math.Max(Math.Max(minWidth, minHeight) + Math.Max(sub.Borders.Width, sub.Borders.Height), 10000.0f);
|
||||
if (Vector2.DistanceSquared(sub.WorldPosition, potentialSpawnPos.Position.ToVector2()) < minDist * minDist)
|
||||
{
|
||||
CoroutineManager.StopCoroutines("forcepos");
|
||||
CoroutineManager.StartCoroutine(ForceShuttleToPos(Level.Loaded.StartPosition - Vector2.UnitY * Level.ShaftHeight, 100.0f), "forcepos");
|
||||
invalid = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case State.Waiting:
|
||||
CountdownStarted = msg.ReadBoolean();
|
||||
ResetShuttle();
|
||||
respawnTimer = msg.ReadSingle();
|
||||
break;
|
||||
case State.Returning:
|
||||
CountdownStarted = false;
|
||||
break;
|
||||
}
|
||||
state = newState;
|
||||
}
|
||||
if (invalid) { continue; }
|
||||
|
||||
msg.ReadPadBits();
|
||||
foreach (Character character in Character.CharacterList)
|
||||
{
|
||||
if (character.IsDead)
|
||||
{
|
||||
//cannot spawn directly over dead bodies
|
||||
if (Math.Abs(character.WorldPosition.X - potentialSpawnPos.Position.X) < minWidth) { invalid = true; break; }
|
||||
if (Math.Abs(character.WorldPosition.Y - potentialSpawnPos.Position.Y) < minHeight) { invalid = true; break; }
|
||||
}
|
||||
else
|
||||
{
|
||||
//cannot spawn near alive characters (to prevent other players from seeing the shuttle
|
||||
//appear out of nowhere, or monsters from immediatelly wrecking the shuttle)
|
||||
if (Vector2.DistanceSquared(character.WorldPosition, potentialSpawnPos.Position.ToVector2()) < 5000.0f * 5000.0f)
|
||||
{
|
||||
invalid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (invalid) { continue; }
|
||||
|
||||
potentialSpawnPositions.Add(potentialSpawnPos);
|
||||
}
|
||||
Vector2 bestSpawnPos = new Vector2(Level.Loaded.StartPosition.X, Level.Loaded.Size.Y + RespawnShuttle.Borders.Height);
|
||||
float bestSpawnPosValue = 0.0f;
|
||||
foreach (var potentialSpawnPos in potentialSpawnPositions)
|
||||
{
|
||||
//the closer the spawnpos is to the main sub, the better
|
||||
float spawnPosValue = 100000.0f / Math.Max(Vector2.Distance(potentialSpawnPos.Position.ToVector2(), Submarine.MainSub.WorldPosition), 1.0f);
|
||||
|
||||
//prefer spawnpoints that are at the left side of the sub (so the shuttle doesn't have to go backwards)
|
||||
if (potentialSpawnPos.Position.X > Submarine.MainSub.WorldPosition.X)
|
||||
{
|
||||
spawnPosValue *= 0.1f;
|
||||
}
|
||||
|
||||
if (spawnPosValue > bestSpawnPosValue)
|
||||
{
|
||||
bestSpawnPos = potentialSpawnPos.Position.ToVector2();
|
||||
bestSpawnPosValue = spawnPosValue;
|
||||
}
|
||||
}
|
||||
|
||||
return bestSpawnPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace Barotrauma.Networking
|
||||
private SerializableProperty property;
|
||||
private string typeString;
|
||||
|
||||
private ServerSettings serverSettings;
|
||||
private object parentObject;
|
||||
|
||||
public string Name
|
||||
{
|
||||
@@ -103,16 +103,42 @@ namespace Barotrauma.Networking
|
||||
|
||||
public object Value
|
||||
{
|
||||
get { return property.GetValue(serverSettings); }
|
||||
get { return property.GetValue(parentObject); }
|
||||
set { property.SetValue(parentObject, value); }
|
||||
}
|
||||
|
||||
public NetPropertyData(ServerSettings serverSettings, SerializableProperty property, string typeString)
|
||||
|
||||
public NetPropertyData(object parentObject, SerializableProperty property, string typeString)
|
||||
{
|
||||
this.property = property;
|
||||
this.typeString = typeString;
|
||||
this.serverSettings = serverSettings;
|
||||
this.parentObject = parentObject;
|
||||
}
|
||||
|
||||
|
||||
public bool PropEquals(object a, object b)
|
||||
{
|
||||
switch (typeString)
|
||||
{
|
||||
case "float":
|
||||
if (!(a is float?)) return false;
|
||||
if (!(b is float?)) return false;
|
||||
return MathUtils.NearlyEqual((float)a, (float)b);
|
||||
case "int":
|
||||
if (!(a is int?)) return false;
|
||||
if (!(b is int?)) return false;
|
||||
return (int)a == (int)b;
|
||||
case "bool":
|
||||
if (!(a is bool?)) return false;
|
||||
if (!(b is bool?)) return false;
|
||||
return (bool)a == (bool)b;
|
||||
case "Enum":
|
||||
if (!(a is Enum)) return false;
|
||||
if (!(b is Enum)) return false;
|
||||
return ((Enum)a).Equals((Enum)b);
|
||||
default:
|
||||
return a.ToString().Equals(b.ToString(), StringComparison.InvariantCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public void Read(NetBuffer msg)
|
||||
{
|
||||
long oldPos = msg.Position;
|
||||
@@ -126,20 +152,24 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
case "float":
|
||||
if (size != 4) break;
|
||||
property.SetValue(serverSettings, msg.ReadFloat());
|
||||
property.SetValue(parentObject, msg.ReadFloat());
|
||||
return;
|
||||
case "int":
|
||||
if (size != 4) break;
|
||||
property.SetValue(parentObject, msg.ReadInt32());
|
||||
return;
|
||||
case "vector2":
|
||||
if (size != 8) break;
|
||||
x = msg.ReadFloat();
|
||||
y = msg.ReadFloat();
|
||||
property.SetValue(serverSettings, new Vector2(x, y));
|
||||
property.SetValue(parentObject, new Vector2(x, y));
|
||||
return;
|
||||
case "vector3":
|
||||
if (size != 12) break;
|
||||
x = msg.ReadFloat();
|
||||
y = msg.ReadFloat();
|
||||
z = msg.ReadFloat();
|
||||
property.SetValue(serverSettings, new Vector3(x, y, z));
|
||||
property.SetValue(parentObject, new Vector3(x, y, z));
|
||||
return;
|
||||
case "vector4":
|
||||
if (size != 16) break;
|
||||
@@ -147,7 +177,7 @@ namespace Barotrauma.Networking
|
||||
y = msg.ReadFloat();
|
||||
z = msg.ReadFloat();
|
||||
w = msg.ReadFloat();
|
||||
property.SetValue(serverSettings, new Vector4(x, y, z, w));
|
||||
property.SetValue(parentObject, new Vector4(x, y, z, w));
|
||||
return;
|
||||
case "color":
|
||||
if (size != 4) break;
|
||||
@@ -155,7 +185,7 @@ namespace Barotrauma.Networking
|
||||
g = msg.ReadByte();
|
||||
b = msg.ReadByte();
|
||||
a = msg.ReadByte();
|
||||
property.SetValue(serverSettings, new Color(r, g, b, a));
|
||||
property.SetValue(parentObject, new Color(r, g, b, a));
|
||||
return;
|
||||
case "rectangle":
|
||||
if (size != 16) break;
|
||||
@@ -163,12 +193,12 @@ namespace Barotrauma.Networking
|
||||
iy = msg.ReadInt32();
|
||||
width = msg.ReadInt32();
|
||||
height = msg.ReadInt32();
|
||||
property.SetValue(serverSettings, new Rectangle(ix, iy, width, height));
|
||||
property.SetValue(parentObject, new Rectangle(ix, iy, width, height));
|
||||
return;
|
||||
default:
|
||||
msg.Position = oldPos; //reset position to properly read the string
|
||||
string incVal = msg.ReadString();
|
||||
property.TrySetValue(serverSettings, incVal);
|
||||
property.TrySetValue(parentObject, incVal);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -178,13 +208,17 @@ namespace Barotrauma.Networking
|
||||
|
||||
public void Write(NetBuffer msg, object overrideValue = null)
|
||||
{
|
||||
if (overrideValue == null) overrideValue = property.GetValue(serverSettings);
|
||||
if (overrideValue == null) overrideValue = property.GetValue(parentObject);
|
||||
switch (typeString)
|
||||
{
|
||||
case "float":
|
||||
msg.WriteVariableUInt32(4);
|
||||
msg.Write((float)overrideValue);
|
||||
break;
|
||||
case "int":
|
||||
msg.WriteVariableUInt32(4);
|
||||
msg.Write((int)overrideValue);
|
||||
break;
|
||||
case "vector2":
|
||||
msg.WriteVariableUInt32(8);
|
||||
msg.Write(((Vector2)overrideValue).X);
|
||||
@@ -232,14 +266,14 @@ namespace Barotrauma.Networking
|
||||
private set;
|
||||
}
|
||||
|
||||
Dictionary<UInt32,NetPropertyData> netProperties;
|
||||
Dictionary<UInt32, NetPropertyData> netProperties;
|
||||
|
||||
partial void InitProjSpecific();
|
||||
|
||||
public ServerSettings(string serverName, int port, int queryPort, int maxPlayers, bool isPublic, bool enableUPnP)
|
||||
{
|
||||
public ServerSettings(NetworkMember networkMember, string serverName, int port, int queryPort, int maxPlayers, bool isPublic, bool enableUPnP)
|
||||
{
|
||||
ServerLog = new ServerLog(serverName);
|
||||
|
||||
|
||||
Voting = new Voting();
|
||||
|
||||
Whitelist = new WhiteList();
|
||||
@@ -265,17 +299,30 @@ namespace Barotrauma.Networking
|
||||
foreach (var property in saveProperties)
|
||||
{
|
||||
object value = property.GetValue(this);
|
||||
if (value == null) continue;
|
||||
if (value == null) { continue; }
|
||||
|
||||
string typeName = SerializableProperty.GetSupportedTypeName(value.GetType());
|
||||
if (typeName != null || property.PropertyType.IsEnum)
|
||||
{
|
||||
NetPropertyData netPropertyData = new NetPropertyData(this, property, typeName);
|
||||
|
||||
UInt32 key = ToolBox.StringToUInt32Hash(property.Name, md5);
|
||||
if (netProperties.ContainsKey(key)){ throw new Exception("Hashing collision in ServerSettings.netProperties: " + netProperties[key] + " has same key as " + property.Name + " (" + key.ToString() + ")"); }
|
||||
netProperties.Add(key, netPropertyData);
|
||||
}
|
||||
}
|
||||
|
||||
if (netProperties.ContainsKey(key)) throw new Exception("Hashing collision in ServerSettings.netProperties: " + netProperties[key] + " has same key as " + property.Name + " (" + key.ToString() + ")");
|
||||
var karmaProperties = SerializableProperty.GetProperties<Serialize>(networkMember.KarmaManager);
|
||||
foreach (var property in karmaProperties)
|
||||
{
|
||||
object value = property.GetValue(networkMember.KarmaManager);
|
||||
if (value == null) { continue; }
|
||||
|
||||
string typeName = SerializableProperty.GetSupportedTypeName(value.GetType());
|
||||
if (typeName != null || property.PropertyType.IsEnum)
|
||||
{
|
||||
NetPropertyData netPropertyData = new NetPropertyData(networkMember.KarmaManager, property, typeName);
|
||||
UInt32 key = ToolBox.StringToUInt32Hash(property.Name, md5);
|
||||
if (netProperties.ContainsKey(key)) { throw new Exception("Hashing collision in ServerSettings.netProperties: " + netProperties[key] + " has same key as " + property.Name + " (" + key.ToString() + ")"); }
|
||||
netProperties.Add(key, netPropertyData);
|
||||
}
|
||||
}
|
||||
@@ -548,7 +595,14 @@ namespace Barotrauma.Networking
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
|
||||
[Serialize(true, true)]
|
||||
public bool AllowFriendlyFire
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
private YesNoMaybe traitorsEnabled;
|
||||
public YesNoMaybe TraitorsEnabled
|
||||
{
|
||||
@@ -631,12 +685,26 @@ namespace Barotrauma.Networking
|
||||
private set;
|
||||
}
|
||||
|
||||
private bool karmaEnabled;
|
||||
[Serialize(false, true)]
|
||||
public bool KarmaEnabled
|
||||
{
|
||||
get { return karmaEnabled; }
|
||||
set
|
||||
{
|
||||
karmaEnabled = value;
|
||||
#if CLIENT
|
||||
if (karmaSettingsBlocker != null) { karmaSettingsBlocker.Visible = !karmaEnabled || karmaPresetDD.SelectedData as string != "custom"; }
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize("default", true)]
|
||||
public string KarmaPreset
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
} = "default";
|
||||
|
||||
[Serialize("sandbox", true)]
|
||||
public string GameModeIdentifier
|
||||
@@ -664,14 +732,14 @@ namespace Barotrauma.Networking
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(60f, true)]
|
||||
[Serialize(60f * 60.0f, true)]
|
||||
public float AutoBanTime
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(360f, true)]
|
||||
[Serialize(60.0f * 60.0f * 24.0f, true)]
|
||||
public float MaxAutoBanTime
|
||||
{
|
||||
get;
|
||||
|
||||
Reference in New Issue
Block a user