Unstable 0.17.0.0
This commit is contained in:
@@ -56,9 +56,9 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (Type.HasFlag(ChatMessageType.Server) || Type.HasFlag(ChatMessageType.Error) || Type.HasFlag(ChatMessageType.ServerLog))
|
||||
{
|
||||
if (translatedText == null || translatedText.Length == 0)
|
||||
if (translatedText.IsNullOrEmpty())
|
||||
{
|
||||
translatedText = TextManager.GetServerMessage(Text);
|
||||
translatedText = TextManager.GetServerMessage(Text).Value;
|
||||
}
|
||||
|
||||
return translatedText;
|
||||
|
||||
@@ -15,11 +15,11 @@ namespace Barotrauma.Networking
|
||||
public UInt64 SteamID;
|
||||
public UInt64 OwnerSteamID;
|
||||
|
||||
public string Language;
|
||||
public LanguageIdentifier Language;
|
||||
|
||||
public UInt16 Ping;
|
||||
|
||||
public string PreferredJob;
|
||||
public Identifier PreferredJob;
|
||||
|
||||
public CharacterTeamType TeamID;
|
||||
|
||||
@@ -148,7 +148,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
private List<Client> kickVoters;
|
||||
|
||||
public HashSet<string> GivenAchievements = new HashSet<string>();
|
||||
public HashSet<Identifier> GivenAchievements = new HashSet<Identifier>();
|
||||
|
||||
public ClientPermissions Permissions = ClientPermissions.None;
|
||||
public List<DebugConsole.Command> PermittedConsoleCommands
|
||||
|
||||
@@ -33,16 +33,16 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
public static List<PermissionPreset> List = new List<PermissionPreset>();
|
||||
|
||||
public readonly string Name;
|
||||
public readonly string Description;
|
||||
public readonly LocalizedString Name;
|
||||
public readonly LocalizedString Description;
|
||||
public readonly ClientPermissions Permissions;
|
||||
public readonly List<DebugConsole.Command> PermittedCommands;
|
||||
|
||||
public PermissionPreset(XElement element)
|
||||
{
|
||||
string name = element.GetAttributeString("name", "");
|
||||
Name = TextManager.Get("permissionpresetname." + name, true) ?? name;
|
||||
Description = TextManager.Get("permissionpresetdescription." + name, true) ?? element.GetAttributeString("description", "");
|
||||
Name = TextManager.Get("permissionpresetname." + name).Fallback(name);
|
||||
Description = TextManager.Get("permissionpresetdescription." + name) .Fallback(element.GetAttributeString("description", ""));
|
||||
|
||||
string permissionsStr = element.GetAttributeString("permissions", "");
|
||||
if (!Enum.TryParse(permissionsStr, out Permissions))
|
||||
@@ -53,7 +53,7 @@ namespace Barotrauma.Networking
|
||||
PermittedCommands = new List<DebugConsole.Command>();
|
||||
if (Permissions.HasFlag(ClientPermissions.ConsoleCommands))
|
||||
{
|
||||
foreach (XElement subElement in element.Elements())
|
||||
foreach (var subElement in element.Elements())
|
||||
{
|
||||
if (!subElement.Name.ToString().Equals("command", StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||
string commandName = subElement.GetAttributeString("name", "");
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace Barotrauma
|
||||
|
||||
class CharacterSpawnInfo : IEntitySpawnInfo
|
||||
{
|
||||
public readonly string identifier;
|
||||
public readonly Identifier Identifier;
|
||||
public readonly CharacterInfo CharacterInfo;
|
||||
|
||||
public readonly Vector2 Position;
|
||||
@@ -125,30 +125,32 @@ namespace Barotrauma
|
||||
|
||||
private readonly Action<Character> onSpawned;
|
||||
|
||||
public CharacterSpawnInfo(string identifier, Vector2 worldPosition, Action<Character> onSpawn = null)
|
||||
public CharacterSpawnInfo(Identifier identifier, Vector2 worldPosition, Action<Character> onSpawn = null)
|
||||
{
|
||||
this.identifier = identifier ?? throw new ArgumentException("ItemSpawnInfo prefab cannot be null.");
|
||||
this.Identifier = identifier;
|
||||
if (identifier.IsEmpty) { throw new ArgumentException($"{nameof(CharacterSpawnInfo)} identifier cannot be null."); }
|
||||
Position = worldPosition;
|
||||
this.onSpawned = onSpawn;
|
||||
}
|
||||
|
||||
public CharacterSpawnInfo(string identifier, Vector2 position, Submarine sub, Action<Character> onSpawn = null)
|
||||
public CharacterSpawnInfo(Identifier identifier, Vector2 position, Submarine sub, Action<Character> onSpawn = null)
|
||||
{
|
||||
this.identifier = identifier ?? throw new ArgumentException("ItemSpawnInfo prefab cannot be null.");
|
||||
this.Identifier = identifier;
|
||||
if (identifier.IsEmpty) { throw new ArgumentException($"{nameof(CharacterSpawnInfo)} identifier cannot be null."); }
|
||||
Position = position;
|
||||
Submarine = sub;
|
||||
this.onSpawned = onSpawn;
|
||||
}
|
||||
|
||||
public CharacterSpawnInfo(string identifier, Vector2 position, CharacterInfo characterInfo, Action<Character> onSpawn = null) : this (identifier, position, onSpawn)
|
||||
public CharacterSpawnInfo(Identifier identifier, Vector2 position, CharacterInfo characterInfo, Action<Character> onSpawn = null) : this (identifier, position, onSpawn)
|
||||
{
|
||||
CharacterInfo = characterInfo;
|
||||
}
|
||||
|
||||
public Entity Spawn()
|
||||
{
|
||||
var character = string.IsNullOrEmpty(identifier) ? null :
|
||||
Character.Create(identifier,
|
||||
var character = Identifier.IsEmpty ? null :
|
||||
Character.Create(Identifier,
|
||||
Submarine == null ? Position : Submarine.Position + Position,
|
||||
ToolBox.RandomSeed(8), CharacterInfo, createNetworkEvent: false);
|
||||
return character;
|
||||
@@ -199,6 +201,7 @@ namespace Barotrauma
|
||||
public readonly Entity Entity;
|
||||
|
||||
public readonly UInt16 OriginalID, OriginalInventoryID;
|
||||
public readonly int OriginalSlotIndex;
|
||||
|
||||
public readonly byte OriginalItemContainerIndex;
|
||||
|
||||
@@ -219,6 +222,7 @@ namespace Barotrauma
|
||||
if (entity is Item item && item.ParentInventory?.Owner != null)
|
||||
{
|
||||
OriginalInventoryID = item.ParentInventory.Owner.ID;
|
||||
OriginalSlotIndex = item.ParentInventory.FindIndex(item);
|
||||
//find the index of the ItemContainer this item is inside to get the item to
|
||||
//spawn in the correct inventory in multi-inventory items like fabricators
|
||||
if (item.Container != null)
|
||||
@@ -250,7 +254,7 @@ namespace Barotrauma
|
||||
return "EntitySpawner";
|
||||
}
|
||||
|
||||
public void AddToSpawnQueue(ItemPrefab itemPrefab, Vector2 worldPosition, float? condition = null, int? quality = null, Action<Item> onSpawned = null)
|
||||
public void AddItemToSpawnQueue(ItemPrefab itemPrefab, Vector2 worldPosition, float? condition = null, int? quality = null, Action<Item> onSpawned = null)
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
if (itemPrefab == null)
|
||||
@@ -263,7 +267,7 @@ namespace Barotrauma
|
||||
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, worldPosition, onSpawned, condition, quality));
|
||||
}
|
||||
|
||||
public void AddToSpawnQueue(ItemPrefab itemPrefab, Vector2 position, Submarine sub, float? condition = null, int? quality = null, Action<Item> onSpawned = null)
|
||||
public void AddItemToSpawnQueue(ItemPrefab itemPrefab, Vector2 position, Submarine sub, float? condition = null, int? quality = null, Action<Item> onSpawned = null)
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
if (itemPrefab == null)
|
||||
@@ -276,7 +280,7 @@ namespace Barotrauma
|
||||
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, position, sub, onSpawned, condition, quality));
|
||||
}
|
||||
|
||||
public void AddToSpawnQueue(ItemPrefab itemPrefab, Inventory inventory, float? condition = null, int? quality = null, Action<Item> onSpawned = null, bool spawnIfInventoryFull = true, bool ignoreLimbSlots = false, InvSlotType slot = InvSlotType.None)
|
||||
public void AddItemToSpawnQueue(ItemPrefab itemPrefab, Inventory inventory, float? condition = null, int? quality = null, Action<Item> onSpawned = null, bool spawnIfInventoryFull = true, bool ignoreLimbSlots = false, InvSlotType slot = InvSlotType.None)
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
if (itemPrefab == null)
|
||||
@@ -294,10 +298,10 @@ namespace Barotrauma
|
||||
});
|
||||
}
|
||||
|
||||
public void AddToSpawnQueue(string speciesName, Vector2 worldPosition, Action<Character> onSpawn = null)
|
||||
public void AddCharacterToSpawnQueue(Identifier speciesName, Vector2 worldPosition, Action<Character> onSpawn = null)
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
if (string.IsNullOrEmpty(speciesName))
|
||||
if (speciesName.IsEmpty)
|
||||
{
|
||||
string errorMsg = "Attempted to add an empty/null species name to entity spawn queue.\n" + Environment.StackTrace.CleanupStackTrace();
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
@@ -307,10 +311,10 @@ namespace Barotrauma
|
||||
spawnQueue.Enqueue(new CharacterSpawnInfo(speciesName, worldPosition, onSpawn));
|
||||
}
|
||||
|
||||
public void AddToSpawnQueue(string speciesName, Vector2 position, Submarine sub, Action<Character> onSpawn = null)
|
||||
public void AddCharacterToSpawnQueue(Identifier speciesName, Vector2 position, Submarine sub, Action<Character> onSpawn = null)
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
if (string.IsNullOrEmpty(speciesName))
|
||||
if (speciesName.IsEmpty)
|
||||
{
|
||||
string errorMsg = "Attempted to add an empty/null species name to entity spawn queue.\n" + Environment.StackTrace.CleanupStackTrace();
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
@@ -320,10 +324,10 @@ namespace Barotrauma
|
||||
spawnQueue.Enqueue(new CharacterSpawnInfo(speciesName, position, sub, onSpawn));
|
||||
}
|
||||
|
||||
public void AddToSpawnQueue(string speciesName, Vector2 worldPosition, CharacterInfo characterInfo, Action<Character> onSpawn = null)
|
||||
public void AddCharacterToSpawnQueue(Identifier speciesName, Vector2 worldPosition, CharacterInfo characterInfo, Action<Character> onSpawn = null)
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
if (string.IsNullOrEmpty(speciesName))
|
||||
if (speciesName.IsEmpty)
|
||||
{
|
||||
string errorMsg = "Attempted to add an empty/null species name to entity spawn queue.\n" + Environment.StackTrace.CleanupStackTrace();
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
@@ -333,10 +337,11 @@ namespace Barotrauma
|
||||
spawnQueue.Enqueue(new CharacterSpawnInfo(speciesName, worldPosition, characterInfo, onSpawn));
|
||||
}
|
||||
|
||||
public void AddToRemoveQueue(Entity entity)
|
||||
public void AddEntityToRemoveQueue(Entity entity)
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
if (removeQueue.Contains(entity) || entity.Removed || entity == null || entity.IdFreed) { return; }
|
||||
if (entity is Item item) { AddItemToRemoveQueue(item); return; }
|
||||
if (entity is Character)
|
||||
{
|
||||
Character character = entity as Character;
|
||||
@@ -352,7 +357,7 @@ namespace Barotrauma
|
||||
removeQueue.Enqueue(entity);
|
||||
}
|
||||
|
||||
public void AddToRemoveQueue(Item item)
|
||||
public void AddItemToRemoveQueue(Item item)
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
if (removeQueue.Contains(item) || item.Removed) { return; }
|
||||
@@ -364,7 +369,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (containedItem != null)
|
||||
{
|
||||
AddToRemoveQueue(containedItem);
|
||||
AddItemToRemoveQueue(containedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
|
||||
enum FileTransferType
|
||||
{
|
||||
Submarine, CampaignSave
|
||||
Submarine, CampaignSave, Mod
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ namespace Barotrauma
|
||||
{ typeof(Single), new ReadWriteBehavior(ReadSingle, WriteSingle) },
|
||||
{ typeof(Double), new ReadWriteBehavior(ReadDouble, WriteDynamic) },
|
||||
{ typeof(String), new ReadWriteBehavior(ReadString, WriteDynamic) },
|
||||
{ typeof(Identifier), new ReadWriteBehavior(ReadIdentifier, WriteDynamic) },
|
||||
{ typeof(Color), new ReadWriteBehavior(ReadColor, WriteColor) },
|
||||
{ typeof(Vector2), new ReadWriteBehavior(ReadVector2, WriteVector2) }
|
||||
}.ToImmutableDictionary();
|
||||
@@ -86,7 +87,7 @@ namespace Barotrauma
|
||||
private static readonly ImmutableDictionary<Predicate<Type>, ReadWriteBehavior> TypePredicates = new Dictionary<Predicate<Type>, ReadWriteBehavior>
|
||||
{
|
||||
// Arrays
|
||||
{ type => type.BaseType?.IsAssignableFrom(typeof(Array)) ?? false, new ReadWriteBehavior(ReadArray, WriteArray) },
|
||||
{ type => typeof(Array).IsAssignableFrom(type.BaseType), new ReadWriteBehavior(ReadArray, WriteArray) },
|
||||
|
||||
// Nested INetSerializableStructs
|
||||
{ type => typeof(INetSerializableStruct).IsAssignableFrom(type), new ReadWriteBehavior(ReadINetSerializableStruct, WriteINetSerializableStruct) },
|
||||
@@ -94,14 +95,77 @@ namespace Barotrauma
|
||||
// Enums
|
||||
{ type => type.IsEnum, new ReadWriteBehavior(ReadEnum, WriteEnum) },
|
||||
|
||||
// Nullable / Optional types
|
||||
{ type => Nullable.GetUnderlyingType(type) != null, new ReadWriteBehavior(ReadNullable, WriteNullable) }
|
||||
// Nullable
|
||||
{ type => Nullable.GetUnderlyingType(type) != null, new ReadWriteBehavior(ReadNullable, WriteNullable) },
|
||||
|
||||
// Option
|
||||
{ type => type.GetGenericTypeDefinition() == typeof(Option<>), new ReadWriteBehavior(ReadOption, WriteOption) }
|
||||
}.ToImmutableDictionary();
|
||||
|
||||
private static readonly Dictionary<Type, MethodInfo> cachedSomeCreateMethods = new Dictionary<Type, MethodInfo>();
|
||||
private static readonly Dictionary<Type, MethodInfo> cachedNoneCreateMethod = new Dictionary<Type, MethodInfo>();
|
||||
|
||||
private static void WriteInvalid(dynamic? obj, NetworkSerialize attribute, IWriteMessage msg) => throw new InvalidOperationException($"Type {obj?.GetType()} cannot be serialized. Did you forget to implement INetSerializableStruct?");
|
||||
|
||||
private static dynamic ReadInvalid(IReadMessage inc, Type type, NetworkSerialize attribute) => throw new InvalidOperationException($"Type {type} cannot be deserialized. Did you forget to implement INetSerializableStruct?");
|
||||
|
||||
private static void WriteOption(dynamic? obj, NetworkSerialize attribute, IWriteMessage msg)
|
||||
{
|
||||
if (obj is null) { throw new ArgumentNullException(nameof(obj), "Tried to write 'null' into a non-nullable type"); }
|
||||
|
||||
Type type = obj.GetType();
|
||||
Type optionType = type.GetGenericTypeDefinition();
|
||||
Type underlyingType = type.GetGenericArguments()[0];
|
||||
|
||||
if (optionType == typeof(None<>))
|
||||
{
|
||||
msg.Write(false);
|
||||
}
|
||||
else if (optionType == typeof(Some<>))
|
||||
{
|
||||
msg.Write(true);
|
||||
if (TryFindBehavior(underlyingType, out ReadWriteBehavior behavior))
|
||||
{
|
||||
behavior.WriteAction(obj.Value, attribute, msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Option type was neither None<> or Some<>");
|
||||
}
|
||||
}
|
||||
|
||||
private static dynamic? ReadOption(IReadMessage inc, Type type, NetworkSerialize attribute)
|
||||
{
|
||||
Type underlyingType = type.GetGenericArguments()[0];
|
||||
bool hasValue = inc.ReadBoolean();
|
||||
if (!hasValue)
|
||||
{
|
||||
return GetCreateMethod(typeof(None<>), underlyingType, cachedNoneCreateMethod).Invoke(null, null);
|
||||
}
|
||||
|
||||
if (TryFindBehavior(underlyingType, out ReadWriteBehavior behavior))
|
||||
{
|
||||
dynamic? value = behavior.ReadAction(inc, underlyingType, attribute);
|
||||
return GetCreateMethod(typeof(Some<>), underlyingType, cachedSomeCreateMethods).Invoke(null, new []{ value });
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"Could not find suitable behavior for type {underlyingType} in {nameof(ReadOption)}");
|
||||
|
||||
static MethodInfo GetCreateMethod(Type optionType, Type type, Dictionary<Type, MethodInfo> cache)
|
||||
{
|
||||
if (cache.TryGetValue(type, out MethodInfo? foundInfo))
|
||||
{
|
||||
return foundInfo;
|
||||
}
|
||||
|
||||
Type genericType = optionType.MakeGenericType(type);
|
||||
MethodInfo info = genericType.GetMethod("Create", BindingFlags.Static | BindingFlags.Public)!;
|
||||
cache.Add(type, info);
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteNullable(dynamic? obj, NetworkSerialize attribute, IWriteMessage msg)
|
||||
{
|
||||
if (obj is { } notNull)
|
||||
@@ -152,9 +216,9 @@ namespace Barotrauma
|
||||
Range<int> range = GetEnumRange(type);
|
||||
int enumIndex = inc.ReadRangedInteger(range.Start, range.End);
|
||||
|
||||
foreach (dynamic e in Enum.GetValues(type))
|
||||
foreach (dynamic? e in Enum.GetValues(type))
|
||||
{
|
||||
if (Convert.ChangeType(e, e.GetTypeCode()) == enumIndex) { return e; }
|
||||
if (Convert.ChangeType(e, e!.GetTypeCode()) == enumIndex) { return e; }
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"An enum {type} with value {enumIndex} could not be found in {nameof(ReadEnum)}");
|
||||
@@ -213,9 +277,9 @@ namespace Barotrauma
|
||||
|
||||
msg.WriteRangedInteger(array.Length, 0, attribute.ArrayMaxSize);
|
||||
|
||||
foreach (dynamic o in array)
|
||||
foreach (dynamic? o in array)
|
||||
{
|
||||
if (TryFindBehavior(o.GetType(), out ReadWriteBehavior behavior))
|
||||
if (TryFindBehavior(o!.GetType(), out ReadWriteBehavior behavior))
|
||||
{
|
||||
behavior.WriteAction(o, attribute, msg);
|
||||
}
|
||||
@@ -285,6 +349,8 @@ namespace Barotrauma
|
||||
private static dynamic ReadDouble(IReadMessage inc, Type type, NetworkSerialize attribute) => inc.ReadDouble();
|
||||
|
||||
private static dynamic ReadString(IReadMessage inc, Type type, NetworkSerialize attribute) => inc.ReadString();
|
||||
|
||||
private static dynamic ReadIdentifier(IReadMessage inc, Type type, NetworkSerialize attribute) => inc.ReadIdentifier();
|
||||
|
||||
private static dynamic ReadColor(IReadMessage inc, Type type, NetworkSerialize attribute) => attribute.IncludeColorAlpha ? inc.ReadColorR8G8B8A8() : inc.ReadColorR8G8B8();
|
||||
|
||||
@@ -408,8 +474,8 @@ namespace Barotrauma
|
||||
/// <see cref="String">string</see><br/>
|
||||
/// <see cref="Microsoft.Xna.Framework.Color"/><br/>
|
||||
/// <see cref="Microsoft.Xna.Framework.Vector2"/><br/>
|
||||
/// In addition arrays, enums and <see cref="Nullable{T}"/> are supported.<br/>
|
||||
/// Using <see cref="Nullable{T}"/> will make the field or property optional
|
||||
/// In addition arrays, enums, <see cref="Nullable{T}"/> and <see cref="Option{T}"/> are supported.<br/>
|
||||
/// Using <see cref="Nullable{T}"/> or <see cref="Option{T}"/> will make the field or property optional.
|
||||
/// </remarks>
|
||||
/// <seealso cref="NetworkSerialize"/>
|
||||
public interface INetSerializableStruct
|
||||
|
||||
@@ -13,105 +13,105 @@ namespace Barotrauma
|
||||
|
||||
public string Name => "KarmaManager";
|
||||
|
||||
public Dictionary<string, SerializableProperty> SerializableProperties { get; private set; }
|
||||
public Dictionary<Identifier, SerializableProperty> SerializableProperties { get; private set; }
|
||||
|
||||
[Serialize(true, true)]
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool ResetKarmaBetweenRounds { get; set; }
|
||||
|
||||
[Serialize(0.1f, true)]
|
||||
[Serialize(0.1f, IsPropertySaveable.Yes)]
|
||||
public float KarmaDecay { get; set; }
|
||||
|
||||
[Serialize(50.0f, true)]
|
||||
[Serialize(50.0f, IsPropertySaveable.Yes)]
|
||||
public float KarmaDecayThreshold { get; set; }
|
||||
|
||||
[Serialize(0.15f, true)]
|
||||
[Serialize(0.15f, IsPropertySaveable.Yes)]
|
||||
public float KarmaIncrease { get; set; }
|
||||
|
||||
[Serialize(50.0f, true)]
|
||||
[Serialize(50.0f, IsPropertySaveable.Yes)]
|
||||
public float KarmaIncreaseThreshold { get; set; }
|
||||
|
||||
[Serialize(0.05f, true)]
|
||||
[Serialize(0.05f, IsPropertySaveable.Yes)]
|
||||
public float StructureRepairKarmaIncrease { get; set; }
|
||||
|
||||
[Serialize(0.1f, true)]
|
||||
[Serialize(0.1f, IsPropertySaveable.Yes)]
|
||||
public float StructureDamageKarmaDecrease { get; set; }
|
||||
|
||||
[Serialize(15.0f, true)]
|
||||
[Serialize(15.0f, IsPropertySaveable.Yes)]
|
||||
public float MaxStructureDamageKarmaDecreasePerSecond { get; set; }
|
||||
|
||||
[Serialize(0.03f, true)]
|
||||
[Serialize(0.03f, IsPropertySaveable.Yes)]
|
||||
public float ItemRepairKarmaIncrease { get; set; }
|
||||
|
||||
[Serialize(0.5f, true)]
|
||||
[Serialize(0.5f, IsPropertySaveable.Yes)]
|
||||
public float ReactorOverheatKarmaDecrease { get; set; }
|
||||
[Serialize(30.0f, true)]
|
||||
[Serialize(30.0f, IsPropertySaveable.Yes)]
|
||||
public float ReactorMeltdownKarmaDecrease { get; set; }
|
||||
|
||||
[Serialize(0.1f, true)]
|
||||
[Serialize(0.1f, IsPropertySaveable.Yes)]
|
||||
public float DamageEnemyKarmaIncrease { get; set; }
|
||||
[Serialize(0.2f, true)]
|
||||
[Serialize(0.2f, IsPropertySaveable.Yes)]
|
||||
public float HealFriendlyKarmaIncrease { get; set; }
|
||||
[Serialize(0.25f, true)]
|
||||
[Serialize(0.25f, IsPropertySaveable.Yes)]
|
||||
public float DamageFriendlyKarmaDecrease { get; set; }
|
||||
|
||||
[Serialize(0.25f, true)]
|
||||
[Serialize(0.25f, IsPropertySaveable.Yes)]
|
||||
public float StunFriendlyKarmaDecrease { get; set; }
|
||||
|
||||
[Serialize(0.3f, true)]
|
||||
[Serialize(0.3f, IsPropertySaveable.Yes)]
|
||||
public float StunFriendlyKarmaDecreaseThreshold { get; set; }
|
||||
|
||||
[Serialize(1.0f, true)]
|
||||
[Serialize(1.0f, IsPropertySaveable.Yes)]
|
||||
public float ExtinguishFireKarmaIncrease { get; set; }
|
||||
|
||||
[Serialize(defaultValue: 15.0f, true)]
|
||||
[Serialize(defaultValue: 15.0f, IsPropertySaveable.Yes)]
|
||||
public float DangerousItemStealKarmaDecrease { get; set; }
|
||||
|
||||
[Serialize(defaultValue: false, true)]
|
||||
[Serialize(defaultValue: false, IsPropertySaveable.Yes)]
|
||||
public bool DangerousItemStealBots { get; set; }
|
||||
|
||||
[Serialize(defaultValue: 0.05f, true)]
|
||||
[Serialize(defaultValue: 0.05f, IsPropertySaveable.Yes)]
|
||||
public float BallastFloraKarmaIncrease { get; set; }
|
||||
|
||||
|
||||
private int allowedWireDisconnectionsPerMinute;
|
||||
[Serialize(5, true)]
|
||||
[Serialize(5, IsPropertySaveable.Yes)]
|
||||
public int AllowedWireDisconnectionsPerMinute
|
||||
{
|
||||
get { return allowedWireDisconnectionsPerMinute; }
|
||||
set { allowedWireDisconnectionsPerMinute = Math.Max(0, value); }
|
||||
}
|
||||
|
||||
[Serialize(6.0f, true)]
|
||||
[Serialize(6.0f, IsPropertySaveable.Yes)]
|
||||
public float WireDisconnectionKarmaDecrease { get; set; }
|
||||
|
||||
[Serialize(0.15f, true)]
|
||||
[Serialize(0.15f, IsPropertySaveable.Yes)]
|
||||
public float SteerSubKarmaIncrease { get; set; }
|
||||
|
||||
[Serialize(15.0f, true)]
|
||||
[Serialize(15.0f, IsPropertySaveable.Yes)]
|
||||
public float SpamFilterKarmaDecrease { get; set; }
|
||||
|
||||
[Serialize(40.0f, true)]
|
||||
[Serialize(40.0f, IsPropertySaveable.Yes)]
|
||||
public float HerpesThreshold { get; set; }
|
||||
|
||||
[Serialize(1.0f, true)]
|
||||
[Serialize(1.0f, IsPropertySaveable.Yes)]
|
||||
public float KickBanThreshold { get; set; }
|
||||
|
||||
[Serialize(0, true)]
|
||||
[Serialize(0, IsPropertySaveable.Yes)]
|
||||
public int KicksBeforeBan { get; set; }
|
||||
|
||||
[Serialize(10.0f, true)]
|
||||
[Serialize(10.0f, IsPropertySaveable.Yes)]
|
||||
public float KarmaNotificationInterval { get; set; }
|
||||
|
||||
[Serialize(120.0f, true)]
|
||||
[Serialize(120.0f, IsPropertySaveable.Yes)]
|
||||
public float AllowedRetaliationTime { get; set; }
|
||||
|
||||
[Serialize(5.0f, true)]
|
||||
[Serialize(5.0f, IsPropertySaveable.Yes)]
|
||||
public float DangerousItemContainKarmaDecrease { get; set; }
|
||||
|
||||
[Serialize(defaultValue: true, true)]
|
||||
[Serialize(defaultValue: true, IsPropertySaveable.Yes)]
|
||||
public bool IsDangerousItemContainKarmaDecreaseIncremental { get; set; }
|
||||
|
||||
[Serialize(30.0f, true)]
|
||||
[Serialize(30.0f, IsPropertySaveable.Yes)]
|
||||
public float MaxDangerousItemContainKarmaDecrease { get; set; }
|
||||
|
||||
private readonly AfflictionPrefab herpesAffliction;
|
||||
@@ -141,7 +141,7 @@ namespace Barotrauma
|
||||
if (doc?.Root != null)
|
||||
{
|
||||
Presets["custom"] = doc.Root;
|
||||
foreach (XElement subElement in doc.Root.Elements())
|
||||
foreach (var subElement in doc.Root.Elements())
|
||||
{
|
||||
string presetName = subElement.GetAttributeString("name", "");
|
||||
Presets[presetName.ToLowerInvariant()] = subElement;
|
||||
|
||||
@@ -13,8 +13,6 @@ namespace Barotrauma.Networking
|
||||
public const int ServerNameMaxLength = 60;
|
||||
public const int ServerMessageMaxLength = 2000;
|
||||
|
||||
public static string MasterServerUrl = GameMain.Config.MasterServerUrl;
|
||||
|
||||
public const float MaxPhysicsBodyVelocity = 64.0f;
|
||||
public const float MaxPhysicsBodyAngularVelocity = 16.0f;
|
||||
|
||||
|
||||
@@ -11,17 +11,17 @@ namespace Barotrauma.Networking
|
||||
public readonly Character TargetCharacter;
|
||||
|
||||
//which entity is this order referring to (hull, reactor, railgun controller, etc)
|
||||
public readonly ISpatialEntity TargetEntity;
|
||||
public ISpatialEntity TargetEntity => Order.TargetSpatialEntity;
|
||||
|
||||
//additional instructions (power up, fire at will, etc)
|
||||
public readonly string OrderOption;
|
||||
public Identifier OrderOption => Order.Option;
|
||||
|
||||
public readonly int OrderPriority;
|
||||
public int OrderPriority => Order.ManualPriority;
|
||||
|
||||
/// <summary>
|
||||
/// Used when the order targets a wall
|
||||
/// </summary>
|
||||
public int? WallSectionIndex { get; set; }
|
||||
public int? WallSectionIndex => Order.WallSectionIndex;
|
||||
|
||||
public bool IsNewOrder { get; }
|
||||
|
||||
@@ -29,55 +29,50 @@ namespace Barotrauma.Networking
|
||||
/// Same as calling <see cref="OrderChatMessage.OrderChatMessage(Order, string, int, string, ISpatialEntity, Character, Character)"/>,
|
||||
/// but the text parameter is set using <see cref="Order.GetChatMessage(string, string, bool, string)"/>
|
||||
/// </summary>
|
||||
public OrderChatMessage(Order order, string orderOption, int priority, ISpatialEntity targetEntity, Character targetCharacter, Character sender, bool isNewOrder = true)
|
||||
: this(order, orderOption, priority,
|
||||
order?.GetChatMessage(targetCharacter?.Name, sender?.CurrentHull?.DisplayName, targetCharacter == sender, orderOption, isNewOrder),
|
||||
targetEntity, targetCharacter, sender, isNewOrder)
|
||||
public OrderChatMessage(Order order, Character targetCharacter, Character sender, bool isNewOrder = true)
|
||||
: this(order,
|
||||
order?.GetChatMessage(targetCharacter?.Name, sender?.CurrentHull?.DisplayName?.Value, givingOrderToSelf: targetCharacter == sender, orderOption: order.Option, isNewOrder: isNewOrder),
|
||||
targetCharacter, sender, isNewOrder)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
public OrderChatMessage(Order order, string orderOption, int priority, string text, ISpatialEntity targetEntity,
|
||||
Character targetCharacter, Character sender, bool isNewOrder = true)
|
||||
public OrderChatMessage(Order order, string text, Character targetCharacter, Character sender, bool isNewOrder = true)
|
||||
: base(sender?.Name, text, ChatMessageType.Order, sender, GameMain.NetworkMember.ConnectedClients.Find(c => c.Character == sender))
|
||||
{
|
||||
Order = order;
|
||||
OrderOption = orderOption;
|
||||
OrderPriority = priority;
|
||||
TargetCharacter = targetCharacter;
|
||||
TargetEntity = targetEntity;
|
||||
IsNewOrder = isNewOrder;
|
||||
}
|
||||
|
||||
public static void WriteOrder(IWriteMessage msg, Order order, Character targetCharacter, ISpatialEntity targetEntity,
|
||||
string orderOption, int orderPriority, int? wallSectionIndex, bool isNewOrder)
|
||||
public static void WriteOrder(IWriteMessage msg, Order order, Character targetCharacter, bool isNewOrder)
|
||||
{
|
||||
msg.Write((byte)Order.PrefabList.IndexOf(order.Prefab));
|
||||
msg.Write(order.Prefab.Identifier);
|
||||
msg.Write(targetCharacter == null ? (UInt16)0 : targetCharacter.ID);
|
||||
msg.Write(targetEntity is Entity ? (targetEntity as Entity).ID : (UInt16)0);
|
||||
msg.Write(order.TargetSpatialEntity is Entity ? (order.TargetEntity as Entity).ID : (UInt16)0);
|
||||
|
||||
// The option of a Dismiss order is written differently so we know what order we target
|
||||
// now that the game supports multiple current orders simultaneously
|
||||
if (order.Prefab.Identifier != "dismissed")
|
||||
if (!order.IsDismissal)
|
||||
{
|
||||
msg.Write((byte)Array.IndexOf(order.Prefab.Options, orderOption));
|
||||
msg.Write((byte)order.Options.IndexOf(order.Option));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!string.IsNullOrEmpty(orderOption))
|
||||
if (order.Option != Identifier.Empty)
|
||||
{
|
||||
msg.Write(true);
|
||||
string[] dismissedOrder = orderOption.Split('.');
|
||||
string[] dismissedOrder = order.Option.Value.Split('.');
|
||||
msg.Write((byte)dismissedOrder.Length);
|
||||
if (dismissedOrder.Length > 0)
|
||||
{
|
||||
string dismissedOrderIdentifier = dismissedOrder[0];
|
||||
var orderPrefab = Order.GetPrefab(dismissedOrderIdentifier);
|
||||
msg.Write((byte)Order.PrefabList.IndexOf(orderPrefab));
|
||||
Identifier dismissedOrderIdentifier = dismissedOrder[0].ToIdentifier();
|
||||
var orderPrefab = OrderPrefab.Prefabs[dismissedOrderIdentifier];
|
||||
msg.Write(dismissedOrderIdentifier);
|
||||
if (dismissedOrder.Length > 1)
|
||||
{
|
||||
string dismissedOrderOption = dismissedOrder[1];
|
||||
msg.Write((byte)Array.IndexOf(orderPrefab.Options, dismissedOrderOption));
|
||||
Identifier dismissedOrderOption = dismissedOrder[1].ToIdentifier();
|
||||
msg.Write((byte)orderPrefab.Options.IndexOf(dismissedOrderOption));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,9 +84,9 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
msg.Write((byte)orderPriority);
|
||||
msg.Write((byte)order.ManualPriority);
|
||||
msg.Write((byte)order.TargetType);
|
||||
if (order.TargetType == Order.OrderTargetType.Position && targetEntity is OrderTarget orderTarget)
|
||||
if (order.TargetType == Order.OrderTargetType.Position && order.TargetSpatialEntity is OrderTarget orderTarget)
|
||||
{
|
||||
msg.Write(true);
|
||||
msg.Write(orderTarget.Position.X);
|
||||
@@ -103,7 +98,7 @@ namespace Barotrauma.Networking
|
||||
msg.Write(false);
|
||||
if (order.TargetType == Order.OrderTargetType.WallSection)
|
||||
{
|
||||
msg.Write((byte)(wallSectionIndex ?? order.WallSectionIndex ?? 0));
|
||||
msg.Write((byte)(order.WallSectionIndex ?? 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,14 +107,14 @@ namespace Barotrauma.Networking
|
||||
|
||||
private void WriteOrder(IWriteMessage msg)
|
||||
{
|
||||
WriteOrder(msg, Order, TargetCharacter, TargetEntity, OrderOption, OrderPriority, WallSectionIndex, IsNewOrder);
|
||||
WriteOrder(msg, Order, TargetCharacter, IsNewOrder);
|
||||
}
|
||||
|
||||
public struct OrderMessageInfo
|
||||
{
|
||||
public int OrderIndex { get; }
|
||||
public Order OrderPrefab { get; }
|
||||
public string OrderOption { get; }
|
||||
public Identifier OrderIdentifier { get; }
|
||||
public OrderPrefab OrderPrefab => OrderPrefab.Prefabs[OrderIdentifier];
|
||||
public Identifier OrderOption { get; }
|
||||
public int? OrderOptionIndex { get; }
|
||||
public Character TargetCharacter { get; }
|
||||
public Order.OrderTargetType TargetType { get; }
|
||||
@@ -129,11 +124,10 @@ namespace Barotrauma.Networking
|
||||
public int Priority { get; }
|
||||
public bool IsNewOrder { get; }
|
||||
|
||||
public OrderMessageInfo(int orderIndex, Order orderPrefab, string orderOption, int? orderOptionIndex, Character targetCharacter,
|
||||
public OrderMessageInfo(Identifier orderIdentifier, Identifier orderOption, int? orderOptionIndex, Character targetCharacter,
|
||||
Order.OrderTargetType targetType, Entity targetEntity, OrderTarget targetPosition, int? wallSectionIndex, int orderPriority, bool isNewOrder)
|
||||
{
|
||||
OrderIndex = orderIndex;
|
||||
OrderPrefab = orderPrefab;
|
||||
OrderIdentifier = orderIdentifier;
|
||||
OrderOption = orderOption;
|
||||
OrderOptionIndex = orderOptionIndex;
|
||||
TargetCharacter = targetCharacter;
|
||||
@@ -148,21 +142,20 @@ namespace Barotrauma.Networking
|
||||
|
||||
public static OrderMessageInfo ReadOrder(IReadMessage msg)
|
||||
{
|
||||
int orderIndex = msg.ReadByte();
|
||||
Identifier orderIdentifier = msg.ReadIdentifier();
|
||||
ushort targetCharacterId = msg.ReadUInt16();
|
||||
Character targetCharacter = targetCharacterId != Entity.NullEntityID ? Entity.FindEntityByID(targetCharacterId) as Character : null;
|
||||
ushort targetEntityId = msg.ReadUInt16();
|
||||
Entity targetEntity = targetEntityId != Entity.NullEntityID ? Entity.FindEntityByID(targetEntityId) : null;
|
||||
|
||||
Order orderPrefab = null;
|
||||
int? optionIndex = null;
|
||||
string orderOption = null;
|
||||
Identifier orderOption = Identifier.Empty;
|
||||
// The option of a Dismiss order is written differently so we know what order we target
|
||||
// now that the game supports multiple current orders simultaneously
|
||||
if (orderIndex >= 0 && orderIndex < Order.PrefabList.Count)
|
||||
if (orderIdentifier != Identifier.Empty)
|
||||
{
|
||||
orderPrefab = Order.PrefabList[orderIndex];
|
||||
if (orderPrefab.Identifier != "dismissed")
|
||||
var orderPrefab = OrderPrefab.Prefabs[orderIdentifier];
|
||||
if (!orderPrefab.IsDismissal)
|
||||
{
|
||||
optionIndex = msg.ReadByte();
|
||||
}
|
||||
@@ -172,11 +165,11 @@ namespace Barotrauma.Networking
|
||||
int identifierCount = msg.ReadByte();
|
||||
if (identifierCount > 0)
|
||||
{
|
||||
int dismissedOrderIndex = msg.ReadByte();
|
||||
Order dismissedOrderPrefab = null;
|
||||
if (dismissedOrderIndex >= 0 && dismissedOrderIndex < Order.PrefabList.Count)
|
||||
Identifier dismissedOrderIdentifier = msg.ReadIdentifier();
|
||||
OrderPrefab dismissedOrderPrefab = null;
|
||||
if (dismissedOrderIdentifier != Identifier.Empty)
|
||||
{
|
||||
dismissedOrderPrefab = Order.PrefabList[dismissedOrderIndex];
|
||||
dismissedOrderPrefab = OrderPrefab.Prefabs[dismissedOrderIdentifier];
|
||||
orderOption = dismissedOrderPrefab.Identifier;
|
||||
}
|
||||
if (identifierCount > 1)
|
||||
@@ -187,7 +180,7 @@ namespace Barotrauma.Networking
|
||||
var options = dismissedOrderPrefab.Options;
|
||||
if (options != null && dismissedOrderOptionIndex >= 0 && dismissedOrderOptionIndex < options.Length)
|
||||
{
|
||||
orderOption += $".{options[dismissedOrderOptionIndex]}";
|
||||
orderOption = $"{orderOption.Value}.{options[dismissedOrderOptionIndex]}".ToIdentifier();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -217,9 +210,8 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
bool isNewOrder = msg.ReadBoolean();
|
||||
|
||||
return new OrderMessageInfo(orderIndex, orderPrefab, orderOption, optionIndex, targetCharacter,
|
||||
orderTargetType, targetEntity, orderTargetPosition, wallSectionIndex, orderPriority, isNewOrder);
|
||||
return new OrderMessageInfo(orderIdentifier, orderOption, optionIndex, targetCharacter,
|
||||
orderTargetType, targetEntity, orderTargetPosition, wallSectionIndex, orderPriority, isNewOrder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace Barotrauma.Networking
|
||||
Double ReadDouble();
|
||||
UInt32 ReadVariableUInt32();
|
||||
String ReadString();
|
||||
Identifier ReadIdentifier();
|
||||
Microsoft.Xna.Framework.Color ReadColorR8G8B8();
|
||||
Microsoft.Xna.Framework.Color ReadColorR8G8B8A8();
|
||||
int ReadRangedInteger(int min, int max);
|
||||
|
||||
+2
-1
@@ -19,11 +19,12 @@ namespace Barotrauma.Networking
|
||||
void WriteColorR8G8B8A8(Microsoft.Xna.Framework.Color val);
|
||||
void WriteVariableUInt32(UInt32 val);
|
||||
void Write(string val);
|
||||
void Write(Identifier val);
|
||||
void WriteRangedInteger(int val, int min, int max);
|
||||
void WriteRangedSingle(Single val, Single min, Single max, int bitCount);
|
||||
void Write(byte[] val, int startIndex, int length);
|
||||
|
||||
void PrepareForSending(ref byte[] outBuf, out bool isCompressed, out int outLength);
|
||||
void PrepareForSending(ref byte[] outBuf, bool compressPastThreshold, out bool isCompressed, out int outLength);
|
||||
|
||||
int BitPosition { get; set; }
|
||||
int BytePosition { get; }
|
||||
|
||||
@@ -454,6 +454,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
lengthBits = value;
|
||||
seekPos = seekPos > lengthBits ? lengthBits : seekPos;
|
||||
MsgWriter.EnsureBufferSize(ref buf, lengthBits);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,6 +541,11 @@ namespace Barotrauma.Networking
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
}
|
||||
|
||||
public void Write(Identifier val)
|
||||
{
|
||||
Write(val.Value);
|
||||
}
|
||||
|
||||
public void WriteRangedInteger(int val, int min, int max)
|
||||
{
|
||||
MsgWriter.WriteRangedInteger(ref buf, ref seekPos, val, min, max);
|
||||
@@ -555,9 +561,9 @@ namespace Barotrauma.Networking
|
||||
MsgWriter.WriteBytes(ref buf, ref seekPos, val, startPos, length);
|
||||
}
|
||||
|
||||
public void PrepareForSending(ref byte[] outBuf, out bool isCompressed, out int length)
|
||||
public void PrepareForSending(ref byte[] outBuf, bool compressPastThreshold, out bool isCompressed, out int length)
|
||||
{
|
||||
if (LengthBytes <= MsgConstants.CompressionThreshold)
|
||||
if (LengthBytes <= MsgConstants.CompressionThreshold || !compressPastThreshold)
|
||||
{
|
||||
isCompressed = false;
|
||||
if (LengthBytes > outBuf.Length) { Array.Resize(ref outBuf, LengthBytes); }
|
||||
@@ -764,6 +770,11 @@ namespace Barotrauma.Networking
|
||||
return MsgReader.ReadString(buf, ref seekPos);
|
||||
}
|
||||
|
||||
public Identifier ReadIdentifier()
|
||||
{
|
||||
return ReadString().ToIdentifier();
|
||||
}
|
||||
|
||||
public Color ReadColorR8G8B8()
|
||||
{
|
||||
return MsgReader.ReadColorR8G8B8(buf, ref seekPos);
|
||||
@@ -773,7 +784,6 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
return MsgReader.ReadColorR8G8B8A8(buf, ref seekPos);
|
||||
}
|
||||
|
||||
|
||||
public int ReadRangedInteger(int min, int max)
|
||||
{
|
||||
@@ -938,6 +948,10 @@ namespace Barotrauma.Networking
|
||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
||||
}
|
||||
|
||||
public void Write(Identifier val)
|
||||
{
|
||||
Write(val.Value);
|
||||
}
|
||||
|
||||
public void WriteRangedInteger(int val, int min, int max)
|
||||
{
|
||||
@@ -1019,6 +1033,11 @@ namespace Barotrauma.Networking
|
||||
return MsgReader.ReadString(buf, ref seekPos);
|
||||
}
|
||||
|
||||
public Identifier ReadIdentifier()
|
||||
{
|
||||
return ReadString().ToIdentifier();
|
||||
}
|
||||
|
||||
public Color ReadColorR8G8B8()
|
||||
{
|
||||
return MsgReader.ReadColorR8G8B8(buf, ref seekPos);
|
||||
@@ -1044,7 +1063,7 @@ namespace Barotrauma.Networking
|
||||
return MsgReader.ReadBytes(buf, ref seekPos, numberOfBytes);
|
||||
}
|
||||
|
||||
public void PrepareForSending(ref byte[] outBuf, out bool isCompressed, out int outLength)
|
||||
public void PrepareForSending(ref byte[] outBuf, bool compressPastThreshold, out bool isCompressed, out int outLength)
|
||||
{
|
||||
throw new InvalidOperationException("ReadWriteMessages are not to be sent");
|
||||
}
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ namespace Barotrauma.Networking
|
||||
protected set;
|
||||
}
|
||||
|
||||
public string Language
|
||||
public LanguageIdentifier Language
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ namespace Barotrauma.Networking
|
||||
//remove respawn items that have been left in the shuttle
|
||||
if (respawnItems.Contains(item))
|
||||
{
|
||||
Spawner.AddToRemoveQueue(item);
|
||||
Spawner.AddItemToRemoveQueue(item);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -272,7 +272,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Hull hull in Hull.hullList)
|
||||
foreach (Hull hull in Hull.HullList)
|
||||
{
|
||||
if (hull.Submarine != RespawnShuttle) { continue; }
|
||||
hull.OxygenPercentage = 100.0f;
|
||||
@@ -295,12 +295,12 @@ namespace Barotrauma.Networking
|
||||
c.Kill(CauseOfDeathType.Unknown, null, true);
|
||||
c.Enabled = false;
|
||||
|
||||
Spawner.AddToRemoveQueue(c);
|
||||
Spawner.AddEntityToRemoveQueue(c);
|
||||
if (c.Inventory != null)
|
||||
{
|
||||
foreach (Item item in c.Inventory.AllItems)
|
||||
{
|
||||
Spawner.AddToRemoveQueue(item);
|
||||
Spawner.AddItemToRemoveQueue(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -322,7 +322,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
public static Affliction GetRespawnPenaltyAffliction()
|
||||
{
|
||||
var respawnPenaltyAffliction = AfflictionPrefab.List.FirstOrDefault(a => a.AfflictionType.Equals("respawnpenalty", StringComparison.OrdinalIgnoreCase));
|
||||
var respawnPenaltyAffliction = AfflictionPrefab.Prefabs.First(a => a.AfflictionType == "respawnpenalty");
|
||||
return respawnPenaltyAffliction?.Instantiate(10.0f);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,23 +10,20 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
private struct LogMessage
|
||||
{
|
||||
public readonly string Text;
|
||||
public readonly string SanitizedText;
|
||||
public readonly RichString Text;
|
||||
public readonly MessageType Type;
|
||||
public readonly List<RichTextData> RichData;
|
||||
|
||||
public LogMessage(string text, MessageType type)
|
||||
{
|
||||
if (type.HasFlag(MessageType.Chat))
|
||||
{
|
||||
Text = $"[{DateTime.Now}]\n {text}";
|
||||
text = $"[{DateTime.Now}]\n {text}";
|
||||
}
|
||||
else
|
||||
{
|
||||
Text = $"[{DateTime.Now}]\n {TextManager.GetServerMessage(text)}";
|
||||
text = $"[{DateTime.Now}]\n {TextManager.GetServerMessage(text)}";
|
||||
}
|
||||
RichData = RichTextData.GetRichTextData(Text, out SanitizedText);
|
||||
|
||||
Text = RichString.Rich(text);
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
@@ -113,7 +110,7 @@ namespace Barotrauma.Networking
|
||||
var newText = new LogMessage(line, messageType);
|
||||
|
||||
#if SERVER
|
||||
DebugConsole.NewMessage(newText.SanitizedText, messageColor[messageType]); //TODO: REMOVE
|
||||
DebugConsole.NewMessage(newText.Text.SanitizedValue, messageColor[messageType]); //TODO: REMOVE
|
||||
#endif
|
||||
|
||||
lines.Enqueue(newText);
|
||||
@@ -173,7 +170,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllLines(filePath, unsavedLines.Select(l => l.SanitizedText));
|
||||
File.WriteAllLines(filePath, unsavedLines.Select(l => l.Text.SanitizedValue));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -97,11 +97,8 @@ namespace Barotrauma.Networking
|
||||
private readonly SerializableProperty property;
|
||||
private readonly string typeString;
|
||||
private readonly object parentObject;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return property.Name; }
|
||||
}
|
||||
|
||||
public Identifier Name => property.Name.ToIdentifier();
|
||||
|
||||
public object Value
|
||||
{
|
||||
@@ -266,7 +263,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
};
|
||||
|
||||
public Dictionary<string, SerializableProperty> SerializableProperties
|
||||
public Dictionary<Identifier, SerializableProperty> SerializableProperties
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
@@ -313,7 +310,7 @@ namespace Barotrauma.Networking
|
||||
if (typeName != null || property.PropertyType.IsEnum)
|
||||
{
|
||||
NetPropertyData netPropertyData = new NetPropertyData(this, property, typeName);
|
||||
UInt32 key = ToolBox.StringToUInt32Hash(property.Name, md5);
|
||||
UInt32 key = ToolBox.IdentifierToUint32Hash(netPropertyData.Name, md5);
|
||||
if (key == 0) { key++; } //0 is reserved to indicate the end of the netproperties section of a message
|
||||
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);
|
||||
@@ -330,7 +327,7 @@ namespace Barotrauma.Networking
|
||||
if (typeName != null || property.PropertyType.IsEnum)
|
||||
{
|
||||
NetPropertyData netPropertyData = new NetPropertyData(networkMember.KarmaManager, property, typeName);
|
||||
UInt32 key = ToolBox.StringToUInt32Hash(property.Name, md5);
|
||||
UInt32 key = ToolBox.IdentifierToUint32Hash(netPropertyData.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);
|
||||
}
|
||||
@@ -382,7 +379,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
public Voting Voting;
|
||||
|
||||
public Dictionary<string, bool> MonsterEnabled { get; private set; }
|
||||
public Dictionary<Identifier, bool> MonsterEnabled { get; private set; }
|
||||
|
||||
public const int MaxExtraCargoItemsOfType = 10;
|
||||
public const int MaxExtraCargoItemTypes = 20;
|
||||
@@ -405,63 +402,63 @@ namespace Barotrauma.Networking
|
||||
|
||||
public WhiteList Whitelist { get; private set; }
|
||||
|
||||
[Serialize(20, true)]
|
||||
[Serialize(20, IsPropertySaveable.Yes)]
|
||||
public int TickRate
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(true, true)]
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool RandomizeSeed
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(true, true)]
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool UseRespawnShuttle
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(300.0f, true)]
|
||||
[Serialize(300.0f, IsPropertySaveable.Yes)]
|
||||
public float RespawnInterval
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(180.0f, true)]
|
||||
[Serialize(180.0f, IsPropertySaveable.Yes)]
|
||||
public float MaxTransportTime
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(0.2f, true)]
|
||||
[Serialize(0.2f, IsPropertySaveable.Yes)]
|
||||
public float MinRespawnRatio
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(60.0f, true)]
|
||||
[Serialize(60.0f, IsPropertySaveable.Yes)]
|
||||
public float AutoRestartInterval
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(false, true)]
|
||||
[Serialize(false, IsPropertySaveable.Yes)]
|
||||
public bool StartWhenClientsReady
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(0.8f, true)]
|
||||
[Serialize(0.8f, IsPropertySaveable.Yes)]
|
||||
public float StartWhenClientsReadyRatio
|
||||
{
|
||||
get;
|
||||
@@ -469,7 +466,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
private bool allowSpectating;
|
||||
[Serialize(true, true)]
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool AllowSpectating
|
||||
{
|
||||
get { return allowSpectating; }
|
||||
@@ -481,21 +478,28 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(true, true)]
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool SaveServerLogs
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(true, true)]
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool AllowModDownloads
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
} = true;
|
||||
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool AllowRagdollButton
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(true, true)]
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool AllowFileTransfers
|
||||
{
|
||||
get;
|
||||
@@ -503,7 +507,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
private bool voiceChatEnabled;
|
||||
[Serialize(true, true)]
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool VoiceChatEnabled
|
||||
{
|
||||
get { return voiceChatEnabled; }
|
||||
@@ -516,7 +520,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
private PlayStyle playstyleSelection;
|
||||
[Serialize(PlayStyle.Casual, true)]
|
||||
[Serialize(PlayStyle.Casual, IsPropertySaveable.Yes)]
|
||||
public PlayStyle PlayStyle
|
||||
{
|
||||
get { return playstyleSelection; }
|
||||
@@ -527,14 +531,14 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(Barotrauma.LosMode.Opaque, true)]
|
||||
[Serialize(Barotrauma.LosMode.Opaque, IsPropertySaveable.Yes)]
|
||||
public LosMode LosMode
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(800, true)]
|
||||
[Serialize(800, IsPropertySaveable.Yes)]
|
||||
public int LinesPerLogFile
|
||||
{
|
||||
get
|
||||
@@ -569,7 +573,7 @@ namespace Barotrauma.Networking
|
||||
#endif
|
||||
}
|
||||
|
||||
[Serialize(true, true)]
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool AllowVoteKick
|
||||
{
|
||||
get
|
||||
@@ -582,7 +586,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(true, true)]
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool AllowEndVoting
|
||||
{
|
||||
get
|
||||
@@ -596,7 +600,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
private bool allowRespawn;
|
||||
[Serialize(true, true)]
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool AllowRespawn
|
||||
{
|
||||
get { return allowRespawn; ; }
|
||||
@@ -608,28 +612,28 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(0, true)]
|
||||
[Serialize(0, IsPropertySaveable.Yes)]
|
||||
public int BotCount
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(16, true)]
|
||||
[Serialize(16, IsPropertySaveable.Yes)]
|
||||
public int MaxBotCount
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(BotSpawnMode.Normal, true)]
|
||||
[Serialize(BotSpawnMode.Normal, IsPropertySaveable.Yes)]
|
||||
public BotSpawnMode BotSpawnMode
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(false, true)]
|
||||
[Serialize(false, IsPropertySaveable.Yes)]
|
||||
public bool DisableBotConversations
|
||||
{
|
||||
get;
|
||||
@@ -642,76 +646,76 @@ namespace Barotrauma.Networking
|
||||
set { selectedLevelDifficulty = MathHelper.Clamp(value, 0.0f, 100.0f); }
|
||||
}
|
||||
|
||||
[Serialize(true, true)]
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool AllowDisguises
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(true, true)]
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool AllowRewiring
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(false, true)]
|
||||
[Serialize(false, IsPropertySaveable.Yes)]
|
||||
public bool LockAllDefaultWires
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(false, true)]
|
||||
[Serialize(false, IsPropertySaveable.Yes)]
|
||||
public bool AllowLinkingWifiToChat
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(true, true)]
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool AllowFriendlyFire
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(false, true)]
|
||||
[Serialize(false, IsPropertySaveable.Yes)]
|
||||
public bool DestructibleOutposts
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(true, true)]
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool KillableNPCs
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(true, true)]
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool BanAfterWrongPassword
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(3, true)]
|
||||
[Serialize(3, IsPropertySaveable.Yes)]
|
||||
public int MaxPasswordRetriesBeforeBan
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize("", true)]
|
||||
[Serialize("", IsPropertySaveable.Yes)]
|
||||
public string SelectedSubmarine
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
[Serialize("", true)]
|
||||
[Serialize("", IsPropertySaveable.Yes)]
|
||||
public string SelectedShuttle
|
||||
{
|
||||
get;
|
||||
@@ -719,7 +723,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
private YesNoMaybe traitorsEnabled;
|
||||
[Serialize(YesNoMaybe.No, true)]
|
||||
[Serialize(YesNoMaybe.No, IsPropertySaveable.Yes)]
|
||||
public YesNoMaybe TraitorsEnabled
|
||||
{
|
||||
get { return traitorsEnabled; }
|
||||
@@ -731,35 +735,35 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(defaultValue: 1, isSaveable: true)]
|
||||
[Serialize(defaultValue: 1, isSaveable: IsPropertySaveable.Yes)]
|
||||
public int TraitorsMinPlayerCount
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(defaultValue: 90.0f, isSaveable: true)]
|
||||
[Serialize(defaultValue: 90.0f, isSaveable: IsPropertySaveable.Yes)]
|
||||
public float TraitorsMinStartDelay
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(defaultValue: 180.0f, isSaveable: true)]
|
||||
[Serialize(defaultValue: 180.0f, isSaveable: IsPropertySaveable.Yes)]
|
||||
public float TraitorsMaxStartDelay
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(defaultValue: 30.0f, isSaveable: true)]
|
||||
[Serialize(defaultValue: 30.0f, isSaveable: IsPropertySaveable.Yes)]
|
||||
public float TraitorsMinRestartDelay
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(defaultValue: 90.0f, isSaveable: true)]
|
||||
[Serialize(defaultValue: 90.0f, isSaveable: IsPropertySaveable.Yes)]
|
||||
public float TraitorsMaxRestartDelay
|
||||
{
|
||||
get;
|
||||
@@ -767,7 +771,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
private SelectionMode subSelectionMode;
|
||||
[Serialize(SelectionMode.Manual, true)]
|
||||
[Serialize(SelectionMode.Manual, IsPropertySaveable.Yes)]
|
||||
public SelectionMode SubSelectionMode
|
||||
{
|
||||
get { return subSelectionMode; }
|
||||
@@ -780,7 +784,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
private SelectionMode modeSelectionMode;
|
||||
[Serialize(SelectionMode.Manual, true)]
|
||||
[Serialize(SelectionMode.Manual, IsPropertySaveable.Yes)]
|
||||
public SelectionMode ModeSelectionMode
|
||||
{
|
||||
get { return modeSelectionMode; }
|
||||
@@ -794,42 +798,42 @@ namespace Barotrauma.Networking
|
||||
|
||||
public BanList BanList { get; private set; }
|
||||
|
||||
[Serialize(0.6f, true)]
|
||||
[Serialize(0.6f, IsPropertySaveable.Yes)]
|
||||
public float EndVoteRequiredRatio
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(0.6f, true)]
|
||||
[Serialize(0.6f, IsPropertySaveable.Yes)]
|
||||
public float SubmarineVoteRequiredRatio
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(30f, true)]
|
||||
[Serialize(30f, IsPropertySaveable.Yes)]
|
||||
public float SubmarineVoteTimeout
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(0.6f, true)]
|
||||
[Serialize(0.6f, IsPropertySaveable.Yes)]
|
||||
public float KickVoteRequiredRatio
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(300.0f, true)]
|
||||
[Serialize(300.0f, IsPropertySaveable.Yes)]
|
||||
public float KillDisconnectedTime
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(600.0f, true)]
|
||||
[Serialize(600.0f, IsPropertySaveable.Yes)]
|
||||
public float KickAFKTime
|
||||
{
|
||||
get;
|
||||
@@ -837,7 +841,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
private bool karmaEnabled;
|
||||
[Serialize(false, true)]
|
||||
[Serialize(false, IsPropertySaveable.Yes)]
|
||||
public bool KarmaEnabled
|
||||
{
|
||||
get { return karmaEnabled; }
|
||||
@@ -851,7 +855,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
private string karmaPreset = "default";
|
||||
[Serialize("default", true)]
|
||||
[Serialize("default", IsPropertySaveable.Yes)]
|
||||
public string KarmaPreset
|
||||
{
|
||||
get { return karmaPreset; }
|
||||
@@ -866,21 +870,21 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize("sandbox", true)]
|
||||
public string GameModeIdentifier
|
||||
[Serialize("sandbox", IsPropertySaveable.Yes)]
|
||||
public Identifier GameModeIdentifier
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize("All", true)]
|
||||
[Serialize("All", IsPropertySaveable.Yes)]
|
||||
public string MissionType
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(8, true)]
|
||||
[Serialize(8, IsPropertySaveable.Yes)]
|
||||
public int MaxPlayers
|
||||
{
|
||||
get { return maxPlayers; }
|
||||
@@ -893,21 +897,21 @@ namespace Barotrauma.Networking
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(60f * 60.0f, true)]
|
||||
[Serialize(60f * 60.0f, IsPropertySaveable.Yes)]
|
||||
public float AutoBanTime
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(60.0f * 60.0f * 24.0f, true)]
|
||||
[Serialize(60.0f * 60.0f * 24.0f, IsPropertySaveable.Yes)]
|
||||
public float MaxAutoBanTime
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(true, true)]
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool RadiationEnabled
|
||||
{
|
||||
get;
|
||||
@@ -916,7 +920,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
private int maxMissionCount = CampaignSettings.DefaultMaxMissionCount;
|
||||
|
||||
[Serialize(CampaignSettings.DefaultMaxMissionCount, true)]
|
||||
[Serialize(CampaignSettings.DefaultMaxMissionCount, IsPropertySaveable.Yes)]
|
||||
public int MaxMissionCount
|
||||
{
|
||||
get { return maxMissionCount; }
|
||||
@@ -962,45 +966,40 @@ namespace Barotrauma.Networking
|
||||
/// <summary>
|
||||
/// A list of int pairs that represent the ranges of UTF-16 codes allowed in client names
|
||||
/// </summary>
|
||||
public List<Pair<int, int>> AllowedClientNameChars
|
||||
public List<Range<int>> AllowedClientNameChars
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
} = new List<Pair<int, int>>();
|
||||
} = new List<Range<int>>();
|
||||
|
||||
private void InitMonstersEnabled()
|
||||
{
|
||||
//monster spawn settings
|
||||
if (MonsterEnabled == null)
|
||||
{
|
||||
List<string> monsterNames1 = CharacterPrefab.Prefabs.Select(p => p.Identifier).ToList();
|
||||
|
||||
MonsterEnabled = new Dictionary<string, bool>();
|
||||
foreach (string s in monsterNames1)
|
||||
{
|
||||
if (!MonsterEnabled.ContainsKey(s)) MonsterEnabled.Add(s, true);
|
||||
}
|
||||
}
|
||||
MonsterEnabled ??= CharacterPrefab.Prefabs.Select(p => (p.Identifier, true)).ToDictionary();
|
||||
}
|
||||
|
||||
public void ReadMonsterEnabled(IReadMessage inc)
|
||||
{
|
||||
InitMonstersEnabled();
|
||||
List<string> monsterNames = MonsterEnabled.Keys.ToList();
|
||||
foreach (string s in monsterNames)
|
||||
List<Identifier> monsterNames = MonsterEnabled.Keys
|
||||
.OrderBy(k => CharacterPrefab.Prefabs[k].UintIdentifier)
|
||||
.ToList();
|
||||
foreach (Identifier s in monsterNames)
|
||||
{
|
||||
MonsterEnabled[s] = inc.ReadBoolean();
|
||||
}
|
||||
inc.ReadPadBits();
|
||||
}
|
||||
|
||||
public void WriteMonsterEnabled(IWriteMessage msg, Dictionary<string, bool> monsterEnabled = null)
|
||||
public void WriteMonsterEnabled(IWriteMessage msg, Dictionary<Identifier, bool> monsterEnabled = null)
|
||||
{
|
||||
//monster spawn settings
|
||||
if (monsterEnabled == null) monsterEnabled = MonsterEnabled;
|
||||
if (monsterEnabled == null) { monsterEnabled = MonsterEnabled; }
|
||||
|
||||
List<string> monsterNames = monsterEnabled.Keys.ToList();
|
||||
foreach (string s in monsterNames)
|
||||
List<Identifier> monsterNames = monsterEnabled.Keys
|
||||
.OrderBy(k => CharacterPrefab.Prefabs[k].UintIdentifier)
|
||||
.ToList();
|
||||
foreach (Identifier s in monsterNames)
|
||||
{
|
||||
msg.Write(monsterEnabled[s]);
|
||||
}
|
||||
@@ -1015,7 +1014,7 @@ namespace Barotrauma.Networking
|
||||
Dictionary<ItemPrefab, int> extraCargo = new Dictionary<ItemPrefab, int>();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
string prefabIdentifier = msg.ReadString();
|
||||
Identifier prefabIdentifier = msg.ReadIdentifier();
|
||||
byte amount = msg.ReadByte();
|
||||
|
||||
if (MapEntityPrefab.Find(null, prefabIdentifier, showErrorMessages: false) is ItemPrefab itemPrefab && amount > 0)
|
||||
@@ -1041,7 +1040,7 @@ namespace Barotrauma.Networking
|
||||
msg.Write((UInt32)ExtraCargo.Count);
|
||||
foreach (KeyValuePair<ItemPrefab, int> kvp in ExtraCargo)
|
||||
{
|
||||
msg.Write(kvp.Key.Identifier ?? "");
|
||||
msg.Write(kvp.Key.Identifier);
|
||||
msg.Write((byte)kvp.Value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,296 +0,0 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
#if USE_STEAM
|
||||
namespace Barotrauma.Steam
|
||||
{
|
||||
static partial class SteamManager
|
||||
{
|
||||
public const int STEAMP2P_OWNER_PORT = 30000;
|
||||
|
||||
public const uint AppID = 602960;
|
||||
|
||||
private static readonly List<string> initializationErrors = new List<string>();
|
||||
public static IEnumerable<string> InitializationErrors
|
||||
{
|
||||
get { return initializationErrors; }
|
||||
}
|
||||
|
||||
public const string MetadataFileName = "filelist.xml";
|
||||
|
||||
public const string CopyIndicatorFileName = ".copying";
|
||||
|
||||
private static readonly Dictionary<string, int> tagCommonness = new Dictionary<string, int>()
|
||||
{
|
||||
{ "submarine", 10 },
|
||||
{ "item", 10 },
|
||||
{ "monster", 8 },
|
||||
{ "art", 8 },
|
||||
{ "mission", 8 },
|
||||
{ "event set", 8 },
|
||||
{ "total conversion", 5 },
|
||||
{ "environment", 5 },
|
||||
{ "item assembly", 5 },
|
||||
{ "language", 5 }
|
||||
};
|
||||
|
||||
private static readonly List<string> popularTags = new List<string>();
|
||||
public static IEnumerable<string> PopularTags
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!isInitialized) { return Enumerable.Empty<string>(); }
|
||||
return popularTags;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool isInitialized;
|
||||
public static bool IsInitialized => isInitialized;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
InitializeProjectSpecific();
|
||||
}
|
||||
|
||||
public static ulong GetSteamID()
|
||||
{
|
||||
if (!isInitialized || !Steamworks.SteamClient.IsValid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Steamworks.SteamClient.SteamId;
|
||||
}
|
||||
|
||||
public static string GetUsername()
|
||||
{
|
||||
if (!isInitialized || !Steamworks.SteamClient.IsValid)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return Steamworks.SteamClient.Name;
|
||||
}
|
||||
|
||||
private static Steamworks.AuthTicket currentTicket = null;
|
||||
public static Steamworks.AuthTicket GetAuthSessionTicket()
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
currentTicket?.Cancel();
|
||||
currentTicket = Steamworks.SteamUser.GetAuthSessionTicket();
|
||||
return currentTicket;
|
||||
}
|
||||
|
||||
public static bool OverlayCustomURL(string url)
|
||||
{
|
||||
if (!isInitialized || !Steamworks.SteamClient.IsValid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Steamworks.SteamFriends.OpenWebOverlay(url);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool UnlockAchievement(string achievementIdentifier)
|
||||
{
|
||||
if (!isInitialized || !Steamworks.SteamClient.IsValid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DebugConsole.Log("Unlocked achievement \"" + achievementIdentifier + "\"");
|
||||
|
||||
var achievements = Steamworks.SteamUserStats.Achievements.ToList();
|
||||
int achIndex = achievements.FindIndex(ach => ach.Identifier == achievementIdentifier);
|
||||
bool unlocked = achIndex >= 0 ? achievements[achIndex].Trigger() : false;
|
||||
if (!unlocked)
|
||||
{
|
||||
//can be caused by an incorrect identifier, but also happens during normal gameplay:
|
||||
//SteamAchievementManager tries to unlock achievements that may or may not exist
|
||||
//(discovered[whateverbiomewasentered], kill[withwhateveritem], kill[somemonster] etc) so that we can add
|
||||
//some types of new achievements without the need for client-side changes.
|
||||
#if DEBUG
|
||||
DebugConsole.NewMessage("Failed to unlock achievement \"" + achievementIdentifier + "\".");
|
||||
#endif
|
||||
}
|
||||
|
||||
return unlocked;
|
||||
}
|
||||
|
||||
public static bool IncrementStat(string statName, int increment)
|
||||
{
|
||||
if (!isInitialized || !Steamworks.SteamClient.IsValid) { return false; }
|
||||
DebugConsole.Log("Incremented stat \"" + statName + "\" by " + increment);
|
||||
bool success = Steamworks.SteamUserStats.AddStat(statName, increment);
|
||||
if (!success)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.NewMessage("Failed to increment stat \"" + statName + "\".");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
StoreStats();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
public static bool IncrementStat(string statName, float increment)
|
||||
{
|
||||
if (!isInitialized || !Steamworks.SteamClient.IsValid) { return false; }
|
||||
DebugConsole.Log("Incremented stat \"" + statName + "\" by " + increment);
|
||||
bool success = Steamworks.SteamUserStats.AddStat(statName, increment);
|
||||
if (!success)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.NewMessage("Failed to increment stat \"" + statName + "\".");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
StoreStats();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
public static int GetStatInt(string statName)
|
||||
{
|
||||
if (!isInitialized || !Steamworks.SteamClient.IsValid) { return 0; }
|
||||
return Steamworks.SteamUserStats.GetStatInt(statName);
|
||||
}
|
||||
|
||||
public static bool StoreStats()
|
||||
{
|
||||
if (!isInitialized || !Steamworks.SteamClient.IsValid) { return false; }
|
||||
DebugConsole.Log("Storing Steam stats...");
|
||||
bool success = Steamworks.SteamUserStats.StoreStats();
|
||||
if (!success)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.NewMessage("Failed to store Steam stats.");
|
||||
#endif
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
public static bool TryGetUnlockedAchievements(out List<Steamworks.Data.Achievement> achievements)
|
||||
{
|
||||
if (!isInitialized || !Steamworks.SteamClient.IsValid)
|
||||
{
|
||||
achievements = null;
|
||||
return false;
|
||||
}
|
||||
achievements = Steamworks.SteamUserStats.Achievements.Where(a => a.State).ToList();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void Update(float deltaTime)
|
||||
{
|
||||
if (!isInitialized) { return; }
|
||||
|
||||
if (Steamworks.SteamClient.IsValid) { Steamworks.SteamClient.RunCallbacks(); }
|
||||
if (Steamworks.SteamServer.IsValid) { Steamworks.SteamServer.RunCallbacks(); }
|
||||
|
||||
SteamAchievementManager.Update(deltaTime);
|
||||
}
|
||||
|
||||
public static void ShutDown()
|
||||
{
|
||||
if (!isInitialized) { return; }
|
||||
|
||||
if (Steamworks.SteamClient.IsValid) { Steamworks.SteamClient.Shutdown(); }
|
||||
if (Steamworks.SteamServer.IsValid) { Steamworks.SteamServer.Shutdown(); }
|
||||
isInitialized = false;
|
||||
}
|
||||
|
||||
public static IEnumerable<ulong> ParseWorkshopIds(string workshopIdData)
|
||||
{
|
||||
string[] workshopIds = workshopIdData.Split(',');
|
||||
foreach (string id in workshopIds)
|
||||
{
|
||||
if (ulong.TryParse(id, out ulong idCast))
|
||||
{
|
||||
yield return idCast;
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<ulong> WorkshopUrlsToIds(IEnumerable<string> urls)
|
||||
{
|
||||
return urls.Select((u) =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(u))
|
||||
{
|
||||
return (ulong)0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetWorkshopItemIDFromUrl(u);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static ulong GetWorkshopItemIDFromUrl(string url)
|
||||
{
|
||||
try
|
||||
{
|
||||
Uri uri = new Uri(url);
|
||||
string idStr = HttpUtility.ParseQueryString(uri.Query)["id"];
|
||||
if (ulong.TryParse(idStr, out ulong id))
|
||||
{
|
||||
return id;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to get Workshop item ID from the url \"" + url + "\"!", e);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static UInt64 SteamIDStringToUInt64(string str)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(str)) { return 0; }
|
||||
UInt64 retVal;
|
||||
if (str.StartsWith("STEAM64_", StringComparison.InvariantCultureIgnoreCase)) { str = str.Substring(8); }
|
||||
if (UInt64.TryParse(str, out retVal) && retVal >(1<<52)) { return retVal; }
|
||||
if (!str.StartsWith("STEAM_", StringComparison.InvariantCultureIgnoreCase)) { return 0; }
|
||||
string[] split = str.Substring(6).Split(':');
|
||||
if (split.Length != 3) { return 0; }
|
||||
|
||||
if (!UInt64.TryParse(split[0], out UInt64 universe)) { return 0; }
|
||||
if (!UInt64.TryParse(split[1], out UInt64 y)) { return 0; }
|
||||
if (!UInt64.TryParse(split[2], out UInt64 accountNumber)) { return 0; }
|
||||
|
||||
UInt64 accountInstance = 1; UInt64 accountType = 1;
|
||||
|
||||
return (universe << 56) | (accountType << 52) | (accountInstance << 32) | (accountNumber << 1) | y;
|
||||
}
|
||||
|
||||
public static string SteamIDUInt64ToString(UInt64 uint64)
|
||||
{
|
||||
UInt64 y = uint64 & 0x1;
|
||||
UInt64 accountNumber = (uint64 >> 1) & 0x7fffffff;
|
||||
UInt64 universe = (uint64 >> 56) & 0xff;
|
||||
|
||||
string retVal = "STEAM_" + universe.ToString() + ":" + y.ToString() + ":" + accountNumber.ToString();
|
||||
|
||||
if (SteamIDStringToUInt64(retVal) != uint64) { return "STEAM64_" + uint64.ToString(); }
|
||||
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user