Merge branch 'master' of bitbucket.org:Regalis11/barotrauma
This commit is contained in:
@@ -127,11 +127,11 @@ namespace Barotrauma
|
||||
//UpdateTransform();
|
||||
}
|
||||
|
||||
public void UpdateTransform()
|
||||
public void UpdateTransform(bool interpolate = true)
|
||||
{
|
||||
Vector2 interpolatedPosition = Physics.Interpolate(prevPosition, position);
|
||||
Vector2 interpolatedPosition = interpolate ? Physics.Interpolate(prevPosition, position) : position;
|
||||
|
||||
float interpolatedZoom = Physics.Interpolate(prevZoom, zoom);
|
||||
float interpolatedZoom = interpolate ? Physics.Interpolate(prevZoom, zoom) : zoom;
|
||||
|
||||
worldView.X = (int)(interpolatedPosition.X - worldView.Width / 2.0);
|
||||
worldView.Y = (int)(interpolatedPosition.Y + worldView.Height / 2.0);
|
||||
@@ -149,6 +149,12 @@ namespace Barotrauma
|
||||
viewMatrix;
|
||||
|
||||
Sound.CameraPos = new Vector3(WorldViewCenter.X, WorldViewCenter.Y, 0.0f);
|
||||
|
||||
if (!interpolate)
|
||||
{
|
||||
prevPosition = position;
|
||||
prevZoom = zoom;
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveCamera(float deltaTime)
|
||||
|
||||
@@ -558,27 +558,12 @@ namespace Barotrauma
|
||||
|
||||
bool wallAttack = (wallAttackPos != Vector2.Zero && state == AiState.Attack);
|
||||
|
||||
message.Write(wallAttack);
|
||||
|
||||
//if (wallAttack)
|
||||
//{
|
||||
// Vector2 relativeWallAttackPos = wallAttackPos - Submarine.Loaded.SimPosition;
|
||||
|
||||
// message.WriteRangedSingle(MathHelper.Clamp(relativeWallAttackPos.X, -50.0f, 50.0f), -50.0f, 50.0f, 10);
|
||||
// message.WriteRangedSingle(MathHelper.Clamp(relativeWallAttackPos.Y, -50.0f, 50.0f), -50.0f, 50.0f, 10);
|
||||
//}
|
||||
|
||||
//message.Write(Velocity.X);
|
||||
//message.Write(Velocity.Y);
|
||||
|
||||
//message.Write(Character.AnimController.RefLimb.SimPosition.X);
|
||||
//message.Write(Character.AnimController.RefLimb.SimPosition.Y);
|
||||
|
||||
//message.Write(wallAttack);
|
||||
|
||||
message.Write(MathUtils.AngleToByte(steeringManager.WanderAngle));
|
||||
//message.WriteRangedSingle(MathHelper.Clamp(updateTargetsTimer,0.0f, UpdateTargetsInterval), 0.0f, UpdateTargetsInterval, 8);
|
||||
//message.WriteRangedSingle(MathHelper.Clamp(raycastTimer, 0.0f, RaycastInterval), 0.0f, RaycastInterval, 8);
|
||||
//message.WriteRangedSingle(MathHelper.Clamp(coolDownTimer, 0.0f, attackCoolDown * 2.0f), 0.0f, attackCoolDown * 2.0f, 8);
|
||||
|
||||
coolDownTimer = MathHelper.Clamp(coolDownTimer, 0.0f, 30.0f);
|
||||
message.WriteRangedSingle(coolDownTimer, 0.0f, 30.0f, 8);
|
||||
|
||||
message.Write(targetEntity==null ? (ushort)0 : (targetEntity as Entity).ID);
|
||||
}
|
||||
@@ -612,9 +597,8 @@ namespace Barotrauma
|
||||
//targetPosition = new Vector2(message.ReadFloat(), message.ReadFloat());
|
||||
|
||||
wanderAngle = MathUtils.ByteToAngle(message.ReadByte());
|
||||
//updateTargetsTimer = message.ReadRangedSingle(0.0f, UpdateTargetsInterval, 8);
|
||||
//raycastTimer = message.ReadRangedSingle(0.0f, RaycastInterval, 8);
|
||||
//coolDownTimer = message.ReadRangedSingle(0.0f, attackCoolDown*2.0f, 8);
|
||||
|
||||
coolDownTimer = message.ReadRangedSingle(0.0f, 30.0f, 8);
|
||||
|
||||
targetID = message.ReadUInt16();
|
||||
}
|
||||
@@ -629,14 +613,10 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
//wallAttackPos = newWallAttackPos;
|
||||
|
||||
steeringManager.WanderAngle = wanderAngle;
|
||||
//this.updateTargetsTimer = updateTargetsTimer;
|
||||
//this.raycastTimer = raycastTimer;
|
||||
//this.coolDownTimer = coolDownTimer;
|
||||
|
||||
if (targetID > 0) targetEntity = Entity.FindEntityByID(targetID) as IDamageable;
|
||||
if (targetID > 0) targetEntity = Entity.FindEntityByID(targetID) as IDamageable;
|
||||
updateTargetsTimer = UpdateTargetsInterval;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -647,14 +627,8 @@ namespace Barotrauma
|
||||
//and if the target attacks the Character, the priority increases)
|
||||
class AITargetMemory
|
||||
{
|
||||
//private AITarget target;
|
||||
private float priority;
|
||||
|
||||
//public AITarget Target
|
||||
//{
|
||||
// get { return target; }
|
||||
//}
|
||||
|
||||
|
||||
public float Priority
|
||||
{
|
||||
get { return priority; }
|
||||
|
||||
@@ -909,9 +909,8 @@ namespace Barotrauma
|
||||
Vector2 shoulderPos = limbJoints[2].WorldAnchorA;
|
||||
Vector2 transformedHoldPos = shoulderPos;
|
||||
|
||||
if (itemPos == Vector2.Zero || Anim == Animation.Climbing)
|
||||
if (itemPos == Vector2.Zero || Anim == Animation.Climbing || (leftHand.Disabled && rightHand.Disabled))
|
||||
{
|
||||
|
||||
if (character.SelectedItems[1] == item)
|
||||
{
|
||||
transformedHoldPos = leftHand.pullJoint.WorldAnchorA - transformedHandlePos[1];
|
||||
|
||||
@@ -815,25 +815,35 @@ namespace Barotrauma
|
||||
{
|
||||
if (inWater)
|
||||
{
|
||||
if (character is AICharacter)
|
||||
if (targetMovement.LengthSquared() > 0.01f)
|
||||
{
|
||||
correctionMovement =
|
||||
Vector2.Lerp(targetMovement, Vector2.Normalize(diff) * MathHelper.Clamp(dist * 8.0f, 0.1f, 8.0f), 0.5f);
|
||||
Vector2.Lerp(targetMovement, Vector2.Normalize(diff) * MathHelper.Clamp(dist * 5.0f, 0.1f, 5.0f), 0.2f);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (Limb limb in Limbs)
|
||||
{
|
||||
//if (limb.body.TargetPosition == Vector2.Zero) continue;
|
||||
refLimb.body.LinearVelocity = Vector2.Lerp(
|
||||
refLimb.LinearVelocity,
|
||||
Vector2.Normalize(diff) * MathHelper.Clamp(dist, 0.0f, 5.0f),
|
||||
0.2f);
|
||||
|
||||
limb.body.SetTransform(limb.SimPosition + Vector2.Normalize(diff) * 0.1f, limb.Rotation);
|
||||
}
|
||||
//foreach (Limb limb in Limbs)
|
||||
//{
|
||||
// //if (limb.body.TargetPosition == Vector2.Zero) continue;
|
||||
// // Vector2.Lerp(limb.LinearVelocity, Vector2.Normalize(diff) * MathHelper.Clamp(dist, 0.0f, 1.0f))
|
||||
// limb.body.LinearVelocity = Vector2.Lerp(
|
||||
// limb.LinearVelocity,
|
||||
// Vector2.Normalize(diff) * MathHelper.Clamp(dist, 0.0f, 5.0f),
|
||||
// 0.2f);
|
||||
|
||||
// //limb.body.TargetVelocity .SetTransform(limb.SimPosition + Vector2.Normalize(diff) * 0.1f, limb.Rotation);
|
||||
//}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//clamp the magnitude of the correction movement between 0.5f - 5.0f
|
||||
Vector2 newCorrectionMovement = Vector2.Normalize(diff) * MathHelper.Clamp(dist * 5.0f, 0.5f, 5.0f);
|
||||
Vector2 newCorrectionMovement = Vector2.Normalize(diff) * MathHelper.Clamp(dist*2.0f, 0.5f, 5.0f);
|
||||
|
||||
//heading in the right direction -> use the ''normal'' movement if it's faster than correctionMovement
|
||||
//i.e. the character is close to the targetposition but the character is still running
|
||||
|
||||
@@ -53,6 +53,8 @@ namespace Barotrauma
|
||||
|
||||
public readonly bool IsNetworkPlayer;
|
||||
|
||||
private bool networkUpdateSent;
|
||||
|
||||
private CharacterInventory inventory;
|
||||
|
||||
public float LastNetworkUpdate;
|
||||
@@ -955,6 +957,17 @@ namespace Barotrauma
|
||||
|
||||
if (isDead) return;
|
||||
|
||||
if (networkUpdateSent)
|
||||
{
|
||||
foreach (Key key in keys)
|
||||
{
|
||||
key.DequeueHit();
|
||||
key.DequeueHeld();
|
||||
}
|
||||
|
||||
networkUpdateSent = false;
|
||||
}
|
||||
|
||||
if (needsAir)
|
||||
{
|
||||
bool protectedFromPressure = PressureProtection > 0.0f;
|
||||
@@ -1421,9 +1434,9 @@ namespace Barotrauma
|
||||
|
||||
return true;
|
||||
case NetworkEventType.EntityUpdate:
|
||||
message.Write(keys[(int)InputType.Use].DequeueHeld);
|
||||
message.Write(keys[(int)InputType.Use].GetHeldQueue);
|
||||
|
||||
bool secondaryHeld = keys[(int)InputType.Aim].DequeueHeld;
|
||||
bool secondaryHeld = keys[(int)InputType.Aim].GetHeldQueue;
|
||||
message.Write(secondaryHeld);
|
||||
|
||||
message.Write(keys[(int)InputType.Left].Held);
|
||||
@@ -1469,6 +1482,8 @@ namespace Barotrauma
|
||||
message.Write(SimPosition.X);
|
||||
message.Write(SimPosition.Y);
|
||||
|
||||
networkUpdateSent = true;
|
||||
|
||||
return true;
|
||||
default:
|
||||
#if DEBUG
|
||||
|
||||
@@ -10,9 +10,9 @@ namespace Barotrauma
|
||||
class StatusEffect
|
||||
{
|
||||
[Flags]
|
||||
public enum TargetType
|
||||
public enum TargetType
|
||||
{
|
||||
This = 1, Parent = 2, Character = 4, Contained = 8, Nearby = 16, UseTarget=32
|
||||
This = 1, Parent = 2, Character = 4, Contained = 8, Nearby = 16, UseTarget = 32, Hull = 64
|
||||
}
|
||||
|
||||
private TargetType targetTypes;
|
||||
@@ -273,20 +273,21 @@ namespace Barotrauma
|
||||
if (disableDeltaTime) deltaTime = 1.0f;
|
||||
|
||||
Type type = value.GetType();
|
||||
if (type == typeof(float))
|
||||
if (type == typeof(float) ||
|
||||
(type == typeof(int) && property.GetValue().GetType() == typeof(float)))
|
||||
{
|
||||
float floatValue = (float)value * deltaTime;
|
||||
float floatValue = Convert.ToSingle(value) * deltaTime;
|
||||
|
||||
if (!setValue) floatValue += (float)property.GetValue();
|
||||
property.TrySetValue(floatValue);
|
||||
}
|
||||
else if (type == typeof(int))
|
||||
else if (type == typeof(int) && value.GetType()==typeof(int))
|
||||
{
|
||||
int intValue = (int)((int)value * deltaTime);
|
||||
if (!setValue) intValue += (int)property.GetValue();
|
||||
property.TrySetValue(intValue);
|
||||
}
|
||||
else if (type == typeof(bool))
|
||||
else if (type == typeof(bool) && value.GetType() == typeof(bool))
|
||||
{
|
||||
property.TrySetValue((bool)value);
|
||||
}
|
||||
@@ -294,6 +295,11 @@ namespace Barotrauma
|
||||
{
|
||||
property.TrySetValue((string)value);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError("Couldn't apply value "+value.ToString()+" ("+type+") to property ''"+property.Name+"'' ("+property.GetValue().GetType()+")! "
|
||||
+"Make sure the type of the value set in the config files matches the type of the property.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateAll(float deltaTime)
|
||||
|
||||
@@ -381,7 +381,8 @@ namespace Barotrauma
|
||||
DebugConsole.ThrowError("Illegal symbols in filename (../)");
|
||||
return;
|
||||
}
|
||||
if (Submarine.SaveCurrent(fileName +".sub")) NewMessage("map saved", Color.Green);
|
||||
|
||||
if (Submarine.SaveCurrent(System.IO.Path.Combine(Submarine.SavePath, fileName +".sub"))) NewMessage("map saved", Color.Green);
|
||||
Submarine.Loaded.CheckForErrors();
|
||||
|
||||
break;
|
||||
@@ -417,6 +418,20 @@ namespace Barotrauma
|
||||
//Hull.DebugDraw = !Hull.DebugDraw;
|
||||
//Ragdoll.DebugDraw = !Ragdoll.DebugDraw;
|
||||
GameMain.DebugDraw = !GameMain.DebugDraw;
|
||||
break;
|
||||
case "sendrandomdata":
|
||||
int messageCount = 1;
|
||||
|
||||
if (commands.Length>1) int.TryParse(commands[1], out messageCount);
|
||||
|
||||
for (int i = 0; i < messageCount; i++ )
|
||||
{
|
||||
if (GameMain.Server!=null)
|
||||
{
|
||||
GameMain.Server.SendRandomData();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case "netstats":
|
||||
if (GameMain.Server == null) return;
|
||||
@@ -479,6 +494,12 @@ namespace Barotrauma
|
||||
DebugConsole.NewMessage("Deleted TutorialSub from the submarine folder", Color.Green);
|
||||
}
|
||||
|
||||
if (System.IO.File.Exists(GameServer.SettingsFile))
|
||||
{
|
||||
System.IO.File.Delete(GameServer.SettingsFile);
|
||||
DebugConsole.NewMessage("Deleted server settings", Color.Green);
|
||||
}
|
||||
|
||||
if (System.IO.File.Exists("crashreport.txt"))
|
||||
{
|
||||
System.IO.File.Delete("crashreport.txt");
|
||||
|
||||
@@ -43,6 +43,18 @@ namespace Barotrauma
|
||||
|
||||
public static Color ScreenOverlayColor;
|
||||
|
||||
private static Sprite submarineIcon, arrow;
|
||||
|
||||
public static Sprite SubmarineIcon
|
||||
{
|
||||
get { return submarineIcon; }
|
||||
}
|
||||
|
||||
public static Sprite Arrow
|
||||
{
|
||||
get { return arrow; }
|
||||
}
|
||||
|
||||
public static void Init(ContentManager content)
|
||||
{
|
||||
GUI.Font = ToolBox.TryLoadFont("SpriteFont1", content);
|
||||
@@ -72,6 +84,12 @@ namespace Barotrauma
|
||||
t = new Texture2D(graphicsDevice, 1, 1);
|
||||
t.SetData(new Color[] { Color.White });// fill the texture with white
|
||||
|
||||
submarineIcon = new Sprite("Content/UI/uiIcons.png", new Rectangle(0, 192, 64, 64), null);
|
||||
submarineIcon.Origin = submarineIcon.size / 2;
|
||||
|
||||
arrow = new Sprite("Content/UI/uiIcons.png", new Rectangle(80, 240, 16, 16), null);
|
||||
arrow.Origin = arrow.size / 2;
|
||||
|
||||
Style = new GUIStyle("Content/UI/style.xml");
|
||||
}
|
||||
|
||||
@@ -304,24 +322,34 @@ namespace Barotrauma
|
||||
return texture;
|
||||
}
|
||||
|
||||
public static bool DrawButton(SpriteBatch sb, Rectangle rect, string text, bool isHoldable = false)
|
||||
public static bool DrawButton(SpriteBatch sb, Rectangle rect, string text, Color color, bool isHoldable = false)
|
||||
{
|
||||
Color color = new Color(200, 200, 200);
|
||||
|
||||
bool clicked = false;
|
||||
|
||||
if (rect.Contains(PlayerInput.MousePosition))
|
||||
{
|
||||
clicked = PlayerInput.LeftButtonHeld();
|
||||
|
||||
color = clicked ? new Color(100, 100, 100) : new Color(250, 250, 250);
|
||||
color = clicked ?
|
||||
new Color((int)(color.R * 0.8f), (int)(color.G * 0.8f), (int)(color.B * 0.8f), color.A) :
|
||||
new Color((int)(color.R * 1.2f), (int)(color.G * 1.2f), (int)(color.B * 1.2f), color.A);
|
||||
|
||||
if (!isHoldable)
|
||||
clicked = PlayerInput.LeftButtonClicked();
|
||||
if (!isHoldable) clicked = PlayerInput.LeftButtonClicked();
|
||||
}
|
||||
|
||||
DrawRectangle(sb, rect, color, true);
|
||||
sb.DrawString(Font, text, new Vector2(rect.X + 10, rect.Y + 10), Color.White);
|
||||
|
||||
Vector2 origin;
|
||||
try
|
||||
{
|
||||
origin = Font.MeasureString(text)/2;
|
||||
}
|
||||
catch
|
||||
{
|
||||
origin = Vector2.Zero;
|
||||
}
|
||||
|
||||
sb.DrawString(Font, text, new Vector2(rect.Center.X, rect.Center.Y) , Color.White, 0.0f, origin, 1.0f, SpriteEffects.None, 0.0f);
|
||||
|
||||
return clicked;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Barotrauma
|
||||
{
|
||||
public static Queue<GUIComponent> MessageBoxes = new Queue<GUIComponent>();
|
||||
|
||||
const int DefaultWidth=400, DefaultHeight=200;
|
||||
const int DefaultWidth=400, DefaultHeight=250;
|
||||
|
||||
//public delegate bool OnClickedHandler(GUIButton button, object obj);
|
||||
//public OnClickedHandler OnClicked;
|
||||
|
||||
@@ -157,8 +157,8 @@ namespace Barotrauma
|
||||
|
||||
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Character));
|
||||
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Item));
|
||||
|
||||
//Event.Init("Content/randomevents.xml");
|
||||
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Items.Components.ItemComponent));
|
||||
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Hull));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -195,7 +195,7 @@ namespace Barotrauma
|
||||
|
||||
|
||||
|
||||
Hull.renderer = new WaterRenderer(GraphicsDevice);
|
||||
Hull.renderer = new WaterRenderer(GraphicsDevice, Content);
|
||||
TitleScreen.LoadState = 1.0f;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
@@ -353,7 +353,7 @@ namespace Barotrauma
|
||||
protected override void OnExiting(object sender, EventArgs args)
|
||||
{
|
||||
if (NetworkMember != null) NetworkMember.Disconnect();
|
||||
|
||||
|
||||
base.OnExiting(sender, args);
|
||||
}
|
||||
|
||||
|
||||
@@ -172,6 +172,29 @@ namespace Barotrauma
|
||||
|
||||
combined = true;
|
||||
}
|
||||
//if moving the item between slots in the same inventory
|
||||
else if (item.ParentInventory == this)
|
||||
{
|
||||
int currentIndex = Array.IndexOf(Items, item);
|
||||
|
||||
Item existingItem = Items[index];
|
||||
|
||||
Items[currentIndex] = null;
|
||||
Items[index] = null;
|
||||
//if the item in the slot can be moved to the slot of the moved item
|
||||
if (TryPutItem(existingItem, currentIndex, false) &&
|
||||
TryPutItem(item, index, false))
|
||||
{
|
||||
new Networking.NetworkEvent(Networking.NetworkEventType.InventoryUpdate, Owner.ID, true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
//swapping the items failed -> move them back to where they were
|
||||
TryPutItem(item, currentIndex, false);
|
||||
TryPutItem(existingItem, index, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return combined;
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
item.Submarine = picker.Submarine;
|
||||
|
||||
if (picker.SelectedConstruction != null && picker.SelectedConstruction.GetComponent<Controller>() != null) return;
|
||||
//if (picker.SelectedConstruction != null && picker.SelectedConstruction.GetComponent<Controller>() != null) return;
|
||||
|
||||
//item.sprite.Depth = picker.AnimController.GetLimb(LimbType.RightHand).sprite.Depth + 0.01f;
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
foreach (Limb limb in character.AnimController.Limbs)
|
||||
{
|
||||
if (limb.WearingItems.Find(w => w.WearableComponent.Item != this.item)==null) continue;
|
||||
if (limb.WearingItems.Find(w => w.WearableComponent.Item == this.item)==null) continue;
|
||||
|
||||
limb.body.ApplyForce(propulsion);
|
||||
}
|
||||
|
||||
@@ -210,6 +210,8 @@ namespace Barotrauma.Items.Components
|
||||
limb.pullJoint.Enabled = false;
|
||||
}
|
||||
|
||||
if (character.SelectedConstruction == this.item) character.SelectedConstruction = null;
|
||||
|
||||
character.AnimController.Anim = AnimController.Animation.None;
|
||||
}
|
||||
|
||||
@@ -225,9 +227,6 @@ namespace Barotrauma.Items.Components
|
||||
IsActive = false;
|
||||
CancelUsing(character);
|
||||
character = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,24 @@ namespace Barotrauma.Items.Components
|
||||
: base(item, element)
|
||||
{
|
||||
IsActive = true;
|
||||
|
||||
var button = new GUIButton(new Rectangle(160, 50, 30, 30), "-", GUI.Style, GuiFrame);
|
||||
button.OnClicked = (GUIButton btn, object obj) =>
|
||||
{
|
||||
targetForce -= 1.0f;
|
||||
item.NewComponentEvent(this, true, false);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
button = new GUIButton(new Rectangle(200, 50, 30, 30), "+", GUI.Style, GuiFrame);
|
||||
button.OnClicked = (GUIButton btn, object obj) =>
|
||||
{
|
||||
targetForce += 1.0f;
|
||||
item.NewComponentEvent(this, true, false);
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
public float CurrentVolume
|
||||
@@ -80,7 +98,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
voltage = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
//isActive = true;
|
||||
@@ -93,18 +111,7 @@ namespace Barotrauma.Items.Components
|
||||
//GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black, true);
|
||||
|
||||
spriteBatch.DrawString(GUI.Font, "Force: " + (int)(targetForce) + " %", new Vector2(GuiFrame.Rect.X + 30, GuiFrame.Rect.Y + 30), Color.White);
|
||||
|
||||
if (GUI.DrawButton(spriteBatch, new Rectangle(GuiFrame.Rect.X + 280, GuiFrame.Rect.Y + 80, 40, 40), "-", true))
|
||||
{
|
||||
targetForce -= 1.0f;
|
||||
item.NewComponentEvent(this, true, false);
|
||||
}
|
||||
|
||||
if (GUI.DrawButton(spriteBatch, new Rectangle(GuiFrame.Rect.X + 280, GuiFrame.Rect.Y + 30, 40, 40), "+", true))
|
||||
{
|
||||
targetForce += 1.0f;
|
||||
item.NewComponentEvent(this, true, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override void UpdateBroken(float deltaTime, Camera cam)
|
||||
|
||||
@@ -286,7 +286,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
public Item(Rectangle newRect, ItemPrefab itemPrefab, Submarine submarine)
|
||||
: base(submarine)
|
||||
: base(itemPrefab, submarine)
|
||||
{
|
||||
prefab = itemPrefab;
|
||||
|
||||
@@ -487,7 +487,8 @@ namespace Barotrauma
|
||||
public void ApplyStatusEffect(StatusEffect effect, ActionType type, float deltaTime, Character character = null)
|
||||
{
|
||||
if (condition == 0.0f && effect.type != ActionType.OnBroken) return;
|
||||
|
||||
if (effect.type != type) return;
|
||||
|
||||
bool hasTargets = (effect.TargetNames == null);
|
||||
|
||||
Item[] containedItems = ContainedItems;
|
||||
@@ -501,10 +502,10 @@ namespace Barotrauma
|
||||
|
||||
List<IPropertyObject> targets = new List<IPropertyObject>();
|
||||
|
||||
if (containedItems!=null)
|
||||
if (containedItems != null)
|
||||
{
|
||||
if (effect.Targets.HasFlag(StatusEffect.TargetType.Contained))
|
||||
{
|
||||
{
|
||||
foreach (Item containedItem in containedItems)
|
||||
{
|
||||
if (containedItem == null) continue;
|
||||
@@ -528,9 +529,14 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!hasTargets) return;
|
||||
|
||||
|
||||
if (effect.Targets.HasFlag(StatusEffect.TargetType.Hull) && CurrentHull != null)
|
||||
{
|
||||
targets.Add(CurrentHull);
|
||||
}
|
||||
|
||||
|
||||
if (effect.Targets.HasFlag(StatusEffect.TargetType.This))
|
||||
{
|
||||
foreach (var pobject in AllPropertyObjects)
|
||||
@@ -550,7 +556,7 @@ namespace Barotrauma
|
||||
// effect.Apply(type, deltaTime, container);
|
||||
// //container.ApplyStatusEffect(effect, type, deltaTime, container);
|
||||
//}
|
||||
|
||||
|
||||
effect.Apply(type, deltaTime, this, targets);
|
||||
|
||||
}
|
||||
@@ -575,7 +581,10 @@ namespace Barotrauma
|
||||
|
||||
|
||||
public override void Update(Camera cam, float deltaTime)
|
||||
{
|
||||
{
|
||||
|
||||
ApplyStatusEffects(ActionType.Always, deltaTime, null);
|
||||
|
||||
foreach (ItemComponent ic in components)
|
||||
{
|
||||
if (ic.Parent != null) ic.IsActive = ic.Parent.IsActive;
|
||||
@@ -1210,7 +1219,7 @@ namespace Barotrauma
|
||||
element.Add(new XAttribute("name", prefab.Name),
|
||||
new XAttribute("ID", ID));
|
||||
|
||||
if (prefab.ResizeHorizontal || prefab.ResizeVertical)
|
||||
if (ResizeHorizontal || ResizeVertical)
|
||||
{
|
||||
element.Add(new XAttribute("rect",
|
||||
(int)(rect.X - Submarine.HiddenSubPosition.X) + "," +
|
||||
|
||||
@@ -116,11 +116,13 @@ namespace Barotrauma
|
||||
|
||||
if (!fireSources[i].CheckOverLap(fireSources[j])) continue;
|
||||
|
||||
fireSources[j].position.X = Math.Min(fireSources[i].position.X, fireSources[j].position.X);
|
||||
float leftEdge = Math.Min(fireSources[i].position.X, fireSources[j].position.X);
|
||||
|
||||
fireSources[j].size.X =
|
||||
Math.Max(fireSources[i].position.X + fireSources[i].size.X, fireSources[j].position.X + fireSources[j].size.X)
|
||||
- fireSources[j].position.X;
|
||||
- leftEdge;
|
||||
|
||||
fireSources[j].position.X = leftEdge;
|
||||
|
||||
fireSources[i].Remove();
|
||||
}
|
||||
@@ -140,7 +142,7 @@ namespace Barotrauma
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
float count = Rand.Range(0.0f, (float)Math.Sqrt(size.X)/3.0f);
|
||||
float count = Rand.Range(0.0f, size.X/50.0f);
|
||||
|
||||
if (fireSoundBasic != null)
|
||||
{
|
||||
@@ -173,10 +175,10 @@ namespace Barotrauma
|
||||
spawnPos, speed, 0.0f, hull);
|
||||
|
||||
if (particle == null) continue;
|
||||
|
||||
|
||||
if (Rand.Int(20) == 1) particle.OnChangeHull = OnChangeHull;
|
||||
|
||||
particle.Size *= MathHelper.Clamp(size.X/100.0f * Math.Max(hull.Oxygen/hull.FullVolume, 0.4f), 0.5f, 4.0f);
|
||||
particle.Size *= MathHelper.Clamp(size.X/60.0f * Math.Max(hull.Oxygen/hull.FullVolume, 0.4f), 0.5f, 3.0f);
|
||||
|
||||
if (size.X < 100.0f) continue;
|
||||
|
||||
@@ -218,7 +220,7 @@ namespace Barotrauma
|
||||
|
||||
if (particleHull.FireSources.Find(fs => pos.X > fs.position.X-100.0f && pos.X < fs.position.X+fs.size.X+100.0f)!=null) return;
|
||||
|
||||
new FireSource(new Vector2(pos.X, particleHull.Rect.Y-particleHull.Rect.Height + 5.0f));
|
||||
new FireSource(new Vector2(pos.X, particleHull.WorldRect.Y-particleHull.Rect.Height + 5.0f));
|
||||
}
|
||||
|
||||
private void DamageCharacters(float deltaTime)
|
||||
|
||||
@@ -20,15 +20,15 @@ namespace Barotrauma
|
||||
//private Sound waterSound;
|
||||
|
||||
//a value between 0.0f-1.0f (0.0 = closed, 1.0f = open)
|
||||
float open;
|
||||
private float open;
|
||||
|
||||
//the force of the water flow which is exerted on physics bodies
|
||||
Vector2 flowForce;
|
||||
private Vector2 flowForce;
|
||||
|
||||
Hull flowTargetHull;
|
||||
private Hull flowTargetHull;
|
||||
|
||||
float higherSurface;
|
||||
float lowerSurface;
|
||||
private float higherSurface;
|
||||
private float lowerSurface;
|
||||
|
||||
|
||||
public float Open
|
||||
@@ -39,11 +39,6 @@ namespace Barotrauma
|
||||
|
||||
public Door ConnectedDoor;
|
||||
|
||||
//public Vector2 FlowForce
|
||||
//{
|
||||
// get { return flowForce*soundVolume; }
|
||||
//}
|
||||
|
||||
public Vector2 LerpedFlowForce
|
||||
{
|
||||
get { return lerpedFlowForce; }
|
||||
@@ -64,6 +59,20 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public override Rectangle Rect
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.Rect;
|
||||
}
|
||||
set
|
||||
{
|
||||
base.Rect = value;
|
||||
|
||||
FindHulls();
|
||||
}
|
||||
}
|
||||
|
||||
public Gap(MapEntityPrefab prefab, Rectangle rectangle)
|
||||
: this (rectangle, Submarine.Loaded)
|
||||
{ }
|
||||
@@ -73,7 +82,7 @@ namespace Barotrauma
|
||||
{ }
|
||||
|
||||
public Gap(Rectangle newRect, bool isHorizontal, Submarine submarine)
|
||||
: base (submarine)
|
||||
: base (MapEntityPrefab.list.Find(m=> m.Name == "Gap"), submarine)
|
||||
{
|
||||
rect = newRect;
|
||||
linkedTo = new ObservableCollection<MapEntity>();
|
||||
@@ -154,9 +163,12 @@ namespace Barotrauma
|
||||
if (GameMain.DebugDraw)
|
||||
{
|
||||
Vector2 center = new Vector2(WorldRect.X + rect.Width / 2.0f, -(WorldRect.Y - rect.Height/ 2.0f));
|
||||
GUI.DrawLine(sb, center, center + flowForce/10.0f, Color.Red);
|
||||
|
||||
GUI.DrawLine(sb, center + Vector2.One * 5.0f, center + lerpedFlowForce / 10.0f + Vector2.One * 5.0f, Color.Orange);
|
||||
|
||||
|
||||
GUI.DrawLine(sb, center, center + new Vector2(flowForce.X, -flowForce.Y)/10.0f, Color.Red);
|
||||
|
||||
GUI.DrawLine(sb, center + Vector2.One * 5.0f, center + new Vector2(lerpedFlowForce.X, -lerpedFlowForce.Y) / 10.0f + Vector2.One * 5.0f, Color.Orange);
|
||||
}
|
||||
|
||||
if (!editing || !ShowGaps) return;
|
||||
@@ -166,34 +178,21 @@ namespace Barotrauma
|
||||
|
||||
GUI.DrawRectangle(sb, new Rectangle(WorldRect.X, -WorldRect.Y, rect.Width, rect.Height), clr * 0.5f, true);
|
||||
|
||||
if (isHorizontal)
|
||||
for (int i = 0; i < linkedTo.Count; i++)
|
||||
{
|
||||
for (int i = 0; i < linkedTo.Count; i++ )
|
||||
{
|
||||
if (linkedTo[i].Rect.Center.X > rect.Center.X)
|
||||
{
|
||||
GUI.DrawRectangle(sb, new Rectangle(WorldRect.Right, -WorldRect.Y, 10, rect.Height), Color.Green * 0.3f, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.DrawRectangle(sb, new Rectangle(WorldRect.X - 10, -WorldRect.Y, 10, rect.Height), Color.Green * 0.3f, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < linkedTo.Count; i++)
|
||||
{
|
||||
if (linkedTo[i].Rect.Y - linkedTo[i].Rect.Height / 2.0f > rect.Y-rect.Height/2.0f)
|
||||
{
|
||||
GUI.DrawRectangle(sb, new Rectangle(WorldRect.X, -WorldRect.Y - 10, rect.Width, 10), Color.Green * 0.3f, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.DrawRectangle(sb, new Rectangle(WorldRect.X, -WorldRect.Y + rect.Height, rect.Width, 10), Color.Green * 0.3f, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Vector2 dir = isHorizontal ?
|
||||
new Vector2(Math.Sign(linkedTo[i].Rect.Center.X - rect.Center.X), 0.0f)
|
||||
: new Vector2(0.0f, Math.Sign((linkedTo[i].Rect.Y - linkedTo[i].Rect.Height / 2.0f) - (rect.Y - rect.Height / 2.0f)));
|
||||
|
||||
Vector2 arrowPos = new Vector2(WorldRect.Center.X, -(WorldRect.Y - WorldRect.Height / 2));
|
||||
arrowPos += new Vector2(dir.X * (WorldRect.Width / 2 + 10), dir.Y * (WorldRect.Height / 2 + 10));
|
||||
|
||||
GUI.Arrow.Draw(sb,
|
||||
arrowPos,
|
||||
clr * 0.8f,
|
||||
GUI.Arrow.Origin, MathUtils.VectorToAngle(dir) + MathHelper.PiOver2,
|
||||
isHorizontal ? new Vector2(rect.Height / 16.0f, 1.0f) : new Vector2(rect.Width / 16.0f, 1.0f));
|
||||
}
|
||||
|
||||
if (isSelected)
|
||||
{
|
||||
@@ -288,6 +287,25 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (flowTargetHull != null && lerpedFlowForce != Vector2.Zero)
|
||||
{
|
||||
foreach (Character character in Character.CharacterList)
|
||||
{
|
||||
if (character.AnimController.CurrentHull != flowTargetHull) continue;
|
||||
|
||||
foreach (Limb limb in character.AnimController.Limbs)
|
||||
{
|
||||
if (!limb.inWater) continue;
|
||||
|
||||
float dist = Vector2.Distance(limb.WorldPosition, WorldPosition);
|
||||
if (dist > lerpedFlowForce.Length()) continue;
|
||||
|
||||
limb.body.ApplyForce(lerpedFlowForce / dist/10.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -444,7 +462,7 @@ namespace Barotrauma
|
||||
|
||||
if (open > 0.0f)
|
||||
{
|
||||
if (hull1.Volume>hull1.FullVolume && hull2.Volume>hull2.FullVolume)
|
||||
if (hull1.Volume > hull1.FullVolume - Hull.MaxCompress && hull2.Volume > hull2.FullVolume - Hull.MaxCompress)
|
||||
{
|
||||
float avgLethality = (hull1.LethalPressure + hull2.LethalPressure) / 2.0f;
|
||||
hull1.LethalPressure = avgLethality;
|
||||
@@ -497,21 +515,31 @@ namespace Barotrauma
|
||||
lowerSurface = rect.Y;
|
||||
|
||||
if (hull1.Volume < hull1.FullVolume - Hull.MaxCompress &&
|
||||
hull1.Surface > -rect.Y)
|
||||
hull1.Surface < rect.Y)
|
||||
{
|
||||
float vel = (rect.Y + hull1.Surface) * 0.03f;
|
||||
|
||||
|
||||
if (rect.X > hull1.Rect.X + hull1.Rect.Width / 2.0f)
|
||||
{
|
||||
float vel = ((rect.Y - rect.Height / 2) - (hull1.Surface + hull1.WaveY[hull1.WaveY.Length - 1])) * 0.1f;
|
||||
|
||||
|
||||
hull1.WaveVel[hull1.WaveY.Length - 1] += vel;
|
||||
hull1.WaveVel[hull1.WaveY.Length - 2] += vel;
|
||||
}
|
||||
else
|
||||
{
|
||||
float vel = ((rect.Y - rect.Height / 2) - (hull1.Surface + hull1.WaveY[0])) * 0.1f;
|
||||
|
||||
|
||||
hull1.WaveVel[0] += vel;
|
||||
hull1.WaveVel[1] += vel;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hull1.LethalPressure += (Submarine.Loaded != null && Submarine.Loaded.AtDamageDepth) ? 100.0f * deltaTime : 10.0f * deltaTime;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -523,7 +551,12 @@ namespace Barotrauma
|
||||
{
|
||||
flowForce = new Vector2(0.0f, delta);
|
||||
}
|
||||
if (hull1.Volume >= hull1.FullVolume - Hull.MaxCompress)
|
||||
{
|
||||
hull1.LethalPressure += (Submarine.Loaded != null && Submarine.Loaded.AtDamageDepth) ? 100.0f * deltaTime : 10.0f * deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void UpdateOxygen()
|
||||
|
||||
@@ -12,7 +12,7 @@ using Lidgren.Network;
|
||||
namespace Barotrauma
|
||||
{
|
||||
|
||||
class Hull : MapEntity
|
||||
class Hull : MapEntity, IPropertyObject
|
||||
{
|
||||
public static List<Hull> hullList = new List<Hull>();
|
||||
private static EntityGrid entityGrid;
|
||||
@@ -20,7 +20,7 @@ namespace Barotrauma
|
||||
public static bool ShowHulls = true;
|
||||
|
||||
public static bool EditWater, EditFire;
|
||||
|
||||
|
||||
public static WaterRenderer renderer;
|
||||
|
||||
private List<FireSource> fireSources;
|
||||
@@ -37,7 +37,11 @@ namespace Barotrauma
|
||||
//how much excess water the room can contain (= more than the volume of the room)
|
||||
public const float MaxCompress = 10000f;
|
||||
|
||||
public readonly Dictionary<string, PropertyDescriptor> properties;
|
||||
public readonly Dictionary<string, ObjectProperty> properties;
|
||||
public Dictionary<string, ObjectProperty> ObjectProperties
|
||||
{
|
||||
get { return properties; }
|
||||
}
|
||||
|
||||
private float lethalPressure;
|
||||
|
||||
@@ -71,6 +75,21 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public override Rectangle Rect
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.Rect;
|
||||
}
|
||||
set
|
||||
{
|
||||
base.Rect = value;
|
||||
|
||||
Item.UpdateHulls();
|
||||
Gap.UpdateHulls();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsLinkable
|
||||
{
|
||||
get { return true; }
|
||||
@@ -148,13 +167,13 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
public Hull(MapEntityPrefab prefab, Rectangle rectangle)
|
||||
: this (rectangle, Submarine.Loaded)
|
||||
: this (prefab, rectangle, Submarine.Loaded)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Hull(Rectangle rectangle, Submarine submarine)
|
||||
: base (submarine)
|
||||
public Hull(MapEntityPrefab prefab, Rectangle rectangle, Submarine submarine)
|
||||
: base (prefab, submarine)
|
||||
{
|
||||
rect = rectangle;
|
||||
|
||||
@@ -162,9 +181,7 @@ namespace Barotrauma
|
||||
|
||||
fireSources = new List<FireSource>();
|
||||
|
||||
properties = TypeDescriptor.GetProperties(GetType())
|
||||
.Cast<PropertyDescriptor>()
|
||||
.ToDictionary(pr => pr.Name);
|
||||
properties = ObjectProperty.GetProperties(this);
|
||||
|
||||
int arraySize = (rectangle.Width / WaveWidth + 1);
|
||||
waveY = new float[arraySize];
|
||||
@@ -434,11 +451,6 @@ namespace Barotrauma
|
||||
update = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
LethalPressure += ( Submarine.Loaded!=null && Submarine.Loaded.AtDamageDepth) ? 100.0f*deltaTime : 10.0f * deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
public void HandleItems(float deltaTime, Item body)
|
||||
@@ -720,7 +732,7 @@ namespace Barotrauma
|
||||
int.Parse(element.Attribute("height").Value));
|
||||
}
|
||||
|
||||
Hull h = new Hull(rect, submarine);
|
||||
Hull h = new Hull(MapEntityPrefab.list.Find(m => m.Name == "Hull"), rect, submarine);
|
||||
|
||||
h.volume = ToolBox.GetAttributeFloat(element, "pressure", 0.0f);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.IO;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -25,20 +26,20 @@ namespace Barotrauma
|
||||
get { return waterTexture; }
|
||||
}
|
||||
|
||||
public WaterRenderer(GraphicsDevice graphicsDevice)
|
||||
public WaterRenderer(GraphicsDevice graphicsDevice, ContentManager content)
|
||||
{
|
||||
#if WINDOWS
|
||||
byte[] bytecode = File.ReadAllBytes("Content/watershader.mgfx");
|
||||
waterEffect = content.Load<Effect>("watershader");
|
||||
#endif
|
||||
#if LINUX
|
||||
byte[] bytecode = File.ReadAllBytes("Content/watershader_opengl.mgfx");
|
||||
#endif
|
||||
|
||||
waterEffect = new Effect(graphicsDevice, bytecode);
|
||||
waterEffect = content.Load<Effect>("watershader_opengl");
|
||||
#endif
|
||||
|
||||
waterTexture = TextureLoader.FromFile("Content/waterbump.png");
|
||||
waterEffect.Parameters["xWaveWidth"].SetValue(0.05f);
|
||||
waterEffect.Parameters["xWaveHeight"].SetValue(0.05f);
|
||||
|
||||
#if WINDOWS
|
||||
//waterEffect.Parameters["xTexture"].SetValue(waterTexture);
|
||||
#endif
|
||||
|
||||
@@ -23,7 +23,9 @@ namespace Barotrauma
|
||||
protected static Vector2 selectionSize = Vector2.Zero;
|
||||
|
||||
protected static Vector2 startMovingPos = Vector2.Zero;
|
||||
|
||||
|
||||
private MapEntityPrefab prefab;
|
||||
|
||||
protected List<ushort> linkedToID;
|
||||
|
||||
//observable collection because some entities may need to be notified when the collection is modified
|
||||
@@ -66,6 +68,9 @@ namespace Barotrauma
|
||||
|
||||
//the position and dimensions of the entity
|
||||
protected Rectangle rect;
|
||||
|
||||
private static bool resizing;
|
||||
private int resizeDirX, resizeDirY;
|
||||
|
||||
public virtual Rectangle Rect {
|
||||
get { return rect; }
|
||||
@@ -139,12 +144,24 @@ namespace Barotrauma
|
||||
set { isSelected = value; }
|
||||
}
|
||||
|
||||
protected bool ResizeHorizontal
|
||||
{
|
||||
get { return prefab == null ? false : prefab.ResizeHorizontal; }
|
||||
}
|
||||
protected bool ResizeVertical
|
||||
{
|
||||
get { return prefab == null ? false : prefab.ResizeVertical; }
|
||||
}
|
||||
|
||||
public virtual string Name
|
||||
{
|
||||
get { return ""; }
|
||||
}
|
||||
|
||||
public MapEntity(Submarine submarine) : base(submarine) { }
|
||||
public MapEntity(MapEntityPrefab prefab, Submarine submarine) : base(submarine)
|
||||
{
|
||||
this.prefab = prefab;
|
||||
}
|
||||
|
||||
public virtual void Move(Vector2 amount)
|
||||
{
|
||||
@@ -232,6 +249,12 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
public static void UpdateSelecting(Camera cam)
|
||||
{
|
||||
if (resizing)
|
||||
{
|
||||
if (selectedList.Count == 0) resizing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (MapEntity e in mapEntityList)
|
||||
{
|
||||
e.isHighlighted = false;
|
||||
@@ -245,7 +268,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
if (GUIComponent.MouseOn != null || !PlayerInput.MouseInsideWindow) return;
|
||||
|
||||
|
||||
if (MapEntityPrefab.Selected != null)
|
||||
{
|
||||
selectionPos = Vector2.Zero;
|
||||
@@ -412,6 +435,11 @@ namespace Barotrauma
|
||||
if (selectedList.Count == 1)
|
||||
{
|
||||
selectedList[0].DrawEditing(spriteBatch, cam);
|
||||
|
||||
if (selectedList[0].ResizeHorizontal || selectedList[0].ResizeVertical)
|
||||
{
|
||||
selectedList[0].DrawResizing(spriteBatch, cam);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -443,6 +471,89 @@ namespace Barotrauma
|
||||
|
||||
public virtual void DrawEditing(SpriteBatch spriteBatch, Camera cam) {}
|
||||
|
||||
private void DrawResizing(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
isHighlighted = true;
|
||||
|
||||
int startX = ResizeHorizontal ? -1 : 0;
|
||||
int StartY = ResizeVertical ? -1 : 0;
|
||||
|
||||
for (int x = startX; x < 2; x += 2)
|
||||
{
|
||||
for (int y = StartY; y < 2; y += 2)
|
||||
{
|
||||
|
||||
Vector2 handlePos = cam.WorldToScreen(Position + new Vector2(x * (rect.Width * 0.5f + 5), y * (rect.Height * 0.5f + 5)));
|
||||
|
||||
bool highlighted = Vector2.Distance(PlayerInput.MousePosition, handlePos)<5.0f;
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, handlePos - new Vector2(3.0f, 3.0f), new Vector2(6.0f, 6.0f), Color.White * (highlighted ? 1.0f : 0.6f), true);
|
||||
|
||||
if (highlighted)
|
||||
{
|
||||
if (PlayerInput.LeftButtonDown())
|
||||
{
|
||||
selectionPos = Vector2.Zero;
|
||||
resizeDirX = x;
|
||||
resizeDirY = y;
|
||||
resizing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (resizing)
|
||||
{
|
||||
|
||||
Vector2 placePosition = new Vector2(rect.X, rect.Y);
|
||||
Vector2 placeSize = new Vector2(rect.Width, rect.Height);
|
||||
|
||||
Vector2 mousePos = Submarine.MouseToWorldGrid(cam);
|
||||
|
||||
if (resizeDirX >0)
|
||||
{
|
||||
mousePos.X = Math.Max(mousePos.X, rect.X + Submarine.GridSize.X);
|
||||
placeSize.X = mousePos.X - placePosition.X;
|
||||
}
|
||||
else if (resizeDirX <0)
|
||||
{
|
||||
mousePos.X = Math.Min(mousePos.X, rect.Right - Submarine.GridSize.X);
|
||||
|
||||
placeSize.X = (placePosition.X + placeSize.X)-mousePos.X;
|
||||
placePosition.X = mousePos.X;
|
||||
}
|
||||
if (resizeDirY < 0)
|
||||
{
|
||||
mousePos.Y = Math.Min(mousePos.Y, rect.Y - Submarine.GridSize.Y);
|
||||
placeSize.Y = placePosition.Y-mousePos.Y;
|
||||
}
|
||||
else if (resizeDirY > 0)
|
||||
{
|
||||
mousePos.Y = Math.Max(mousePos.Y, rect.Y - rect.Height + Submarine.GridSize.X);
|
||||
|
||||
placeSize.Y = mousePos.Y - (rect.Y - rect.Height);
|
||||
placePosition.Y = mousePos.Y;
|
||||
}
|
||||
|
||||
if ((int)placePosition.X != rect.X || (int)placePosition.Y != rect.Y || (int)placeSize.X != rect.Width || (int)placeSize.Y != rect.Height)
|
||||
{
|
||||
Rect = new Rectangle((int)placePosition.X, (int)placePosition.Y, (int)placeSize.X, (int)placeSize.Y);
|
||||
}
|
||||
|
||||
if (!PlayerInput.LeftButtonHeld())
|
||||
{
|
||||
resizing = false;
|
||||
}
|
||||
|
||||
//if (resizeHorizontal) placeSize.X = position.X - placePosition.X;
|
||||
//if (resizeVertical) placeSize.Y = placePosition.Y - position.Y;
|
||||
|
||||
//Rectangle newRect = Submarine.AbsRect(placePosition, placeSize);
|
||||
//newRect.Width = (int)Math.Max(newRect.Width, Submarine.GridSize.X);
|
||||
//newRect.Height = (int)Math.Max(newRect.Height, Submarine.GridSize.Y);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<MapEntity> FindMapEntities(Vector2 pos)
|
||||
{
|
||||
List<MapEntity> foundEntities = new List<MapEntity>();
|
||||
@@ -518,13 +629,6 @@ namespace Barotrauma
|
||||
{
|
||||
mapEntityList[i].OnMapLoaded();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//mapEntityList.Sort((x, y) =>
|
||||
//{
|
||||
// return x.Name.CompareTo(y.Name);
|
||||
//});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
public Structure(Rectangle rectangle, StructurePrefab sp, Submarine submarine)
|
||||
: base(submarine)
|
||||
: base(sp, submarine)
|
||||
{
|
||||
if (rectangle.Width == 0 || rectangle.Height == 0) return;
|
||||
|
||||
|
||||
@@ -511,17 +511,17 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool SaveCurrent(string fileName)
|
||||
public static bool SaveCurrent(string filePath)
|
||||
{
|
||||
if (loaded==null)
|
||||
{
|
||||
loaded = new Submarine(fileName);
|
||||
loaded = new Submarine(filePath);
|
||||
// return;
|
||||
}
|
||||
|
||||
loaded.filePath = SavePath + System.IO.Path.DirectorySeparatorChar + fileName;
|
||||
loaded.filePath = filePath;
|
||||
|
||||
return loaded.SaveAs(SavePath+System.IO.Path.DirectorySeparatorChar+fileName);
|
||||
return loaded.SaveAs(filePath);
|
||||
}
|
||||
|
||||
public void CheckForErrors()
|
||||
@@ -590,7 +590,7 @@ namespace Barotrauma
|
||||
{
|
||||
try
|
||||
{
|
||||
filePaths.AddRange(Directory.GetDirectories(subDirectory));
|
||||
filePaths.AddRange(Directory.GetFiles(subDirectory).ToList());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -604,6 +604,8 @@ namespace Barotrauma
|
||||
//Map savedMap = new Map(mapPath);
|
||||
SavedSubmarines.Add(new Submarine(path));
|
||||
}
|
||||
|
||||
if (GameMain.NetLobbyScreen!=null) GameMain.NetLobbyScreen.UpdateSubList();
|
||||
}
|
||||
|
||||
private XDocument OpenDoc(string file)
|
||||
@@ -629,12 +631,16 @@ namespace Barotrauma
|
||||
|
||||
if (extension == ".sub")
|
||||
{
|
||||
Stream stream = SaveUtil.DecompressFiletoStream(file);
|
||||
if (stream == null)
|
||||
Stream stream = null;
|
||||
try
|
||||
{
|
||||
DebugConsole.ThrowError("Loading submarine ''" + file + "'' failed!");
|
||||
return null;
|
||||
stream = SaveUtil.DecompressFiletoStream(file);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Loading submarine ''" + file + "'' failed!", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -713,37 +719,42 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 topLeft = new Vector2(Hull.hullList[0].Rect.X, Hull.hullList[0].Rect.Y);
|
||||
Vector2 bottomRight = new Vector2(Hull.hullList[0].Rect.X, Hull.hullList[0].Rect.Y);
|
||||
foreach (Hull hull in Hull.hullList)
|
||||
Vector2 center = Vector2.Zero;
|
||||
|
||||
if (Hull.hullList.Any())
|
||||
{
|
||||
if (hull.Rect.X < topLeft.X) topLeft.X = hull.Rect.X;
|
||||
if (hull.Rect.Y > topLeft.Y) topLeft.Y = hull.Rect.Y;
|
||||
|
||||
if (hull.Rect.Right > bottomRight.X) bottomRight.X = hull.Rect.Right;
|
||||
if (hull.Rect.Y - hull.Rect.Height < bottomRight.Y) bottomRight.Y = hull.Rect.Y - hull.Rect.Height;
|
||||
}
|
||||
|
||||
Vector2 center = (topLeft + bottomRight) / 2.0f;
|
||||
center.X -= center.X % GridSize.X;
|
||||
center.Y -= center.Y % GridSize.Y;
|
||||
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
var wire = item.GetComponent<Items.Components.Wire>();
|
||||
if (wire == null) continue;
|
||||
|
||||
for (int i = 0; i < wire.Nodes.Count; i++)
|
||||
Vector2 topLeft = new Vector2(Hull.hullList[0].Rect.X, Hull.hullList[0].Rect.Y);
|
||||
Vector2 bottomRight = new Vector2(Hull.hullList[0].Rect.X, Hull.hullList[0].Rect.Y);
|
||||
foreach (Hull hull in Hull.hullList)
|
||||
{
|
||||
wire.Nodes[i] -= center;
|
||||
}
|
||||
}
|
||||
if (hull.Rect.X < topLeft.X) topLeft.X = hull.Rect.X;
|
||||
if (hull.Rect.Y > topLeft.Y) topLeft.Y = hull.Rect.Y;
|
||||
|
||||
for (int i = 0; i < MapEntity.mapEntityList.Count; i++)
|
||||
{
|
||||
if (MapEntity.mapEntityList[i].Submarine == null) continue;
|
||||
if (hull.Rect.Right > bottomRight.X) bottomRight.X = hull.Rect.Right;
|
||||
if (hull.Rect.Y - hull.Rect.Height < bottomRight.Y) bottomRight.Y = hull.Rect.Y - hull.Rect.Height;
|
||||
}
|
||||
|
||||
center = (topLeft + bottomRight) / 2.0f;
|
||||
center.X -= center.X % GridSize.X;
|
||||
center.Y -= center.Y % GridSize.Y;
|
||||
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
var wire = item.GetComponent<Items.Components.Wire>();
|
||||
if (wire == null) continue;
|
||||
|
||||
for (int i = 0; i < wire.Nodes.Count; i++)
|
||||
{
|
||||
wire.Nodes[i] -= center;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MapEntity.mapEntityList.Count; i++)
|
||||
{
|
||||
if (MapEntity.mapEntityList[i].Submarine == null) continue;
|
||||
|
||||
MapEntity.mapEntityList[i].Move(-center);
|
||||
MapEntity.mapEntityList[i].Move(-center);
|
||||
}
|
||||
}
|
||||
|
||||
subBody = new SubmarineBody(this);
|
||||
|
||||
@@ -226,25 +226,32 @@ namespace Barotrauma
|
||||
if (dist > 1000.0f)
|
||||
{
|
||||
Vector2 moveAmount = ConvertUnits.ToSimUnits((Vector2)targetPosition) - body.Position;
|
||||
Vector2 displayerMoveAmount = ConvertUnits.ToDisplayUnits(moveAmount);
|
||||
Vector2 displayMoveAmount = ConvertUnits.ToDisplayUnits(moveAmount);
|
||||
|
||||
body.SetTransform(body.Position + moveAmount, 0.0f);
|
||||
if (Character.Controlled != null) Character.Controlled.CursorPosition += displayerMoveAmount;
|
||||
if (Character.Controlled != null) Character.Controlled.CursorPosition += displayMoveAmount;
|
||||
|
||||
GameMain.GameScreen.Cam.Position += displayerMoveAmount;
|
||||
GameMain.GameScreen.Cam.UpdateTransform();
|
||||
GameMain.GameScreen.Cam.Position += displayMoveAmount;
|
||||
if (GameMain.GameScreen.Cam.TargetPos!=Vector2.Zero) GameMain.GameScreen.Cam.TargetPos += displayMoveAmount;
|
||||
GameMain.GameScreen.Cam.UpdateTransform(false);
|
||||
|
||||
submarine.SetPrevTransform(submarine.Position);
|
||||
submarine.UpdateTransform();
|
||||
targetPosition = null;
|
||||
}
|
||||
else if (dist > 50.0f)
|
||||
{
|
||||
Vector2 moveAmount = Vector2.Normalize((Vector2)targetPosition - Position);
|
||||
moveAmount *= ConvertUnits.ToSimUnits(Math.Min(dist, 100.0f));
|
||||
Vector2 displayerMoveAmount = ConvertUnits.ToDisplayUnits(moveAmount);
|
||||
Vector2 displayMoveAmount = ConvertUnits.ToDisplayUnits(moveAmount);
|
||||
|
||||
body.SetTransform(body.Position + moveAmount * deltaTime, 0.0f);
|
||||
|
||||
GameMain.GameScreen.Cam.Position += displayerMoveAmount * deltaTime;
|
||||
if (Character.Controlled != null) Character.Controlled.CursorPosition += displayerMoveAmount;
|
||||
GameMain.GameScreen.Cam.Position += displayMoveAmount * deltaTime;
|
||||
if (GameMain.GameScreen.Cam.TargetPos != Vector2.Zero) GameMain.GameScreen.Cam.TargetPos += displayMoveAmount;
|
||||
if (Character.Controlled != null) Character.Controlled.CursorPosition += displayMoveAmount;
|
||||
|
||||
//GameMain.GameScreen.Cam.UpdateTransform(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
public WayPoint(Rectangle newRect, Submarine submarine)
|
||||
: base (submarine)
|
||||
: base (null, submarine)
|
||||
{
|
||||
rect = newRect;
|
||||
linkedTo = new ObservableCollection<MapEntity>();
|
||||
|
||||
@@ -1,70 +1,313 @@
|
||||
using Lidgren.Network;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
class FileStreamReceiver
|
||||
class FileStreamReceiver : IDisposable
|
||||
{
|
||||
private NetClient s_client;
|
||||
private ulong s_length;
|
||||
private ulong s_received;
|
||||
private FileStream s_writeStream;
|
||||
private int s_timeStarted;
|
||||
const int MaxFileSize = 1000000;
|
||||
|
||||
public delegate void OnFinished(FileStreamReceiver fileStreamReceiver);
|
||||
private OnFinished onFinished;
|
||||
|
||||
private NetClient client;
|
||||
private ulong length;
|
||||
private ulong received;
|
||||
private FileStream writeStream;
|
||||
private int timeStarted;
|
||||
|
||||
private string downloadFolder;
|
||||
|
||||
private FileTransferMessageType fileType;
|
||||
|
||||
public string FileName
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public ulong FileSize
|
||||
{
|
||||
get { return length; }
|
||||
}
|
||||
|
||||
public ulong Received
|
||||
{
|
||||
get { return received; }
|
||||
}
|
||||
|
||||
public FileTransferMessageType FileType
|
||||
{
|
||||
get { return fileType; }
|
||||
}
|
||||
|
||||
public FileTransferStatus Status
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string ErrorMessage
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public float BytesPerSecond
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public FileStreamReceiver(NetClient client)
|
||||
public float Progress
|
||||
{
|
||||
s_client = client;
|
||||
get { return (float)received / (float)length; }
|
||||
}
|
||||
|
||||
public FileStreamReceiver(NetClient client, string filePath, FileTransferMessageType fileType, OnFinished onFinished)
|
||||
{
|
||||
this.client = client;
|
||||
|
||||
this.downloadFolder = filePath;
|
||||
this.fileType = fileType;
|
||||
|
||||
this.onFinished = onFinished;
|
||||
|
||||
Status = FileTransferStatus.NotStarted;
|
||||
}
|
||||
|
||||
public void ReadMessage(NetIncomingMessage inc)
|
||||
{
|
||||
int chunkLen = inc.LengthBytes;
|
||||
if (s_length == 0)
|
||||
try
|
||||
{
|
||||
s_length = inc.ReadUInt64();
|
||||
string filename = inc.ReadString();
|
||||
s_writeStream = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
s_timeStarted = Environment.TickCount;
|
||||
TryReadMessage(inc);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ErrorMessage = "Error while receiving file ''"+FileName+"'' {"+e.Message+"}";
|
||||
DeleteFile();
|
||||
|
||||
if (onFinished != null) onFinished(this);
|
||||
}
|
||||
}
|
||||
|
||||
private bool ValidateInitialData(byte type, string fileName, ulong fileSize)
|
||||
{
|
||||
if (fileSize > MaxFileSize)
|
||||
{
|
||||
ErrorMessage = "File too large (" + MathUtils.GetBytesReadable((long)fileSize) + ")";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type != (byte)fileType)
|
||||
{
|
||||
ErrorMessage = "Unexpected file type ''" + type + "'' (expected " + fileType + ")";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Regex.Match(fileName, @"^[\w\- ]+[\w\-. ]*$").Success)
|
||||
{
|
||||
ErrorMessage = "Illegal characters in file name ''" + fileName + "''";
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case (byte)FileTransferMessageType.Submarine:
|
||||
if (Path.GetExtension(fileName) != ".sub")
|
||||
{
|
||||
ErrorMessage = "Wrong file extension ''" + Path.GetExtension(fileName) + "''! (Expected .sub)";
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void DeleteFile()
|
||||
{
|
||||
if (FileName == null) return;
|
||||
|
||||
string file = Path.Combine(downloadFolder, FileName);
|
||||
|
||||
if (writeStream!=null)
|
||||
{
|
||||
writeStream.Flush();
|
||||
writeStream.Close();
|
||||
writeStream.Dispose();
|
||||
writeStream = null;
|
||||
}
|
||||
|
||||
Status = FileTransferStatus.Canceled;
|
||||
|
||||
if (File.Exists(file))
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(file);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Couldn't delete file ''" + file + "''!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void TryReadMessage(NetIncomingMessage inc)
|
||||
{
|
||||
if (Status == FileTransferStatus.Error ||
|
||||
Status == FileTransferStatus.Finished ||
|
||||
Status == FileTransferStatus.Canceled) return;
|
||||
|
||||
byte transferMessageType = inc.ReadByte();
|
||||
|
||||
//int chunkLen = inc.LengthBytes;
|
||||
if (length == 0)
|
||||
{
|
||||
if (transferMessageType != (byte)FileTransferMessageType.Initiate) return;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(downloadFolder) && !Directory.Exists(downloadFolder))
|
||||
{
|
||||
Directory.CreateDirectory(downloadFolder);
|
||||
}
|
||||
|
||||
byte fileTypeByte = inc.ReadByte();
|
||||
|
||||
|
||||
length = inc.ReadUInt64();
|
||||
FileName = inc.ReadString();
|
||||
|
||||
if (!ValidateInitialData(fileTypeByte, FileName, length))
|
||||
{
|
||||
Status = FileTransferStatus.Error;
|
||||
DeleteFile();
|
||||
if (onFinished != null) onFinished(this);
|
||||
return;
|
||||
}
|
||||
|
||||
writeStream = new FileStream(Path.Combine(downloadFolder, FileName), FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
timeStarted = Environment.TickCount;
|
||||
|
||||
Status = FileTransferStatus.NotStarted;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] all = inc.ReadBytes(inc.LengthBytes);
|
||||
s_received += (ulong)all.Length;
|
||||
s_writeStream.Write(all, 0, all.Length);
|
||||
|
||||
if (received + (ulong)inc.LengthBytes > length*1.1f)
|
||||
{
|
||||
ErrorMessage = "Receiving more data than expected (> " + MathUtils.GetBytesReadable((long)(received + (ulong)inc.LengthBytes)) + ")";
|
||||
Status = FileTransferStatus.Error;
|
||||
if (onFinished != null) onFinished(this);
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] all = inc.ReadBytes(inc.LengthBytes - inc.PositionInBytes);
|
||||
received += (ulong)all.Length;
|
||||
writeStream.Write(all, 0, all.Length);
|
||||
|
||||
int passed = Environment.TickCount - s_timeStarted;
|
||||
int passed = Environment.TickCount - timeStarted;
|
||||
float psec = passed / 1000.0f;
|
||||
|
||||
BytesPerSecond = s_received / psec;
|
||||
BytesPerSecond = received / psec;
|
||||
|
||||
Status = FileTransferStatus.Receiving;
|
||||
|
||||
if (s_received >= s_length)
|
||||
{
|
||||
s_writeStream.Flush();
|
||||
s_writeStream.Close();
|
||||
s_writeStream.Dispose();
|
||||
|
||||
Status = FileTransferStatus.Finished;
|
||||
if (received >= length)
|
||||
{
|
||||
writeStream.Flush();
|
||||
writeStream.Close();
|
||||
writeStream.Dispose();
|
||||
writeStream = null;
|
||||
|
||||
Status = IsReceivedFileValid() ? FileTransferStatus.Finished : FileTransferStatus.Error;
|
||||
if (onFinished!=null) onFinished(this);
|
||||
|
||||
if (Status == FileTransferStatus.Error) DeleteFile();
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsReceivedFileValid()
|
||||
{
|
||||
switch (fileType)
|
||||
{
|
||||
case FileTransferMessageType.Submarine:
|
||||
string file = Path.Combine(downloadFolder, FileName);
|
||||
Stream stream = null;
|
||||
|
||||
try
|
||||
{
|
||||
stream = SaveUtil.DecompressFiletoStream(file);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ErrorMessage = "Loading submarine ''" + file + "'' failed! {"+ e.Message + "}";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stream == null)
|
||||
{
|
||||
ErrorMessage = "Decompressing submarine file''" + file + "'' failed!";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
stream.Position = 0;
|
||||
|
||||
XmlReaderSettings settings = new XmlReaderSettings();
|
||||
settings.DtdProcessing = DtdProcessing.Prohibit;
|
||||
settings.IgnoreProcessingInstructions = true;
|
||||
|
||||
using (var reader = XmlReader.Create(stream, settings))
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
stream.Close();
|
||||
stream.Dispose();
|
||||
|
||||
ErrorMessage = "Parsing file ''"+file+"'' failed! The file may not be a valid submarine file.";
|
||||
return false;
|
||||
}
|
||||
|
||||
stream.Close();
|
||||
stream.Dispose();
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (writeStream != null)
|
||||
{
|
||||
writeStream.Flush();
|
||||
writeStream.Close();
|
||||
writeStream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,21 +1,35 @@
|
||||
using Lidgren.Network;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
enum FileTransferStatus
|
||||
{
|
||||
NotStarted, Sending, Receiving, Finished, Error
|
||||
NotStarted, Sending, Receiving, Finished, Error, Canceled
|
||||
}
|
||||
|
||||
class FileStreamSender
|
||||
enum FileTransferMessageType
|
||||
{
|
||||
Unknown, Initiate, Submarine, Cancel
|
||||
}
|
||||
|
||||
class FileStreamSender : IDisposable
|
||||
{
|
||||
public static TimeSpan MaxTransferDuration = new TimeSpan(0, 2, 0);
|
||||
|
||||
private FileStream inputStream;
|
||||
private int sentOffset;
|
||||
private int chunkLen;
|
||||
private byte[] tempBuffer;
|
||||
private NetConnection connection;
|
||||
|
||||
float waitTimer;
|
||||
|
||||
DateTime startingTime;
|
||||
|
||||
private FileTransferMessageType fileType;
|
||||
|
||||
public FileTransferStatus Status
|
||||
{
|
||||
get;
|
||||
@@ -28,35 +42,84 @@ namespace Barotrauma.Networking
|
||||
private set;
|
||||
}
|
||||
|
||||
|
||||
public static FileStreamSender Create(NetConnection conn, string fileName)
|
||||
public string FilePath
|
||||
{
|
||||
if (!File.Exists(fileName))
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public float Progress
|
||||
{
|
||||
get { return inputStream == null ? 0.0f : (float)sentOffset / (float)inputStream.Length; }
|
||||
}
|
||||
|
||||
public int Sent
|
||||
{
|
||||
get { return sentOffset; }
|
||||
}
|
||||
|
||||
public long FileSize
|
||||
{
|
||||
get { return inputStream == null ? 0 : inputStream.Length; }
|
||||
}
|
||||
|
||||
public static FileStreamSender Create(NetConnection conn, string filePath, FileTransferMessageType fileType)
|
||||
{
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
DebugConsole.ThrowError("Sending a file failed. File ''"+fileName+"'' not found.");
|
||||
DebugConsole.ThrowError("Sending a file failed. File ''"+filePath+"'' not found.");
|
||||
return null;
|
||||
}
|
||||
|
||||
return new FileStreamSender(conn, fileName);
|
||||
FileStreamSender sender = null;
|
||||
|
||||
try
|
||||
{
|
||||
sender = new FileStreamSender(conn, filePath, fileType);
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Couldn't open file ''"+filePath+"''",e);
|
||||
}
|
||||
|
||||
return sender;
|
||||
}
|
||||
|
||||
private FileStreamSender(NetConnection conn, string fileName)
|
||||
private FileStreamSender(NetConnection conn, string filePath, FileTransferMessageType fileType)
|
||||
{
|
||||
connection = conn;
|
||||
inputStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
chunkLen = connection.Peer.Configuration.MaximumTransmissionUnit - 20;
|
||||
inputStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
chunkLen = connection.Peer.Configuration.MaximumTransmissionUnit - 100;
|
||||
tempBuffer = new byte[chunkLen];
|
||||
sentOffset = 0;
|
||||
|
||||
FileName = fileName;
|
||||
FilePath = filePath;
|
||||
FileName = Path.GetFileName(filePath);
|
||||
|
||||
this.fileType = fileType;
|
||||
|
||||
Status = FileTransferStatus.NotStarted;
|
||||
|
||||
startingTime = DateTime.Now;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (inputStream == null) return;
|
||||
if (inputStream == null ||
|
||||
Status == FileTransferStatus.Canceled ||
|
||||
Status == FileTransferStatus.Error ||
|
||||
Status == FileTransferStatus.Finished) return;
|
||||
|
||||
if (DateTime.Now > startingTime + MaxTransferDuration)
|
||||
{
|
||||
CancelTransfer();
|
||||
return;
|
||||
}
|
||||
|
||||
waitTimer -= deltaTime;
|
||||
if (waitTimer > 0.0f) return;
|
||||
|
||||
if (!connection.CanSendImmediately(NetDeliveryMethod.ReliableOrdered, 1)) return;
|
||||
|
||||
// send another part of the file!
|
||||
@@ -70,7 +133,10 @@ namespace Barotrauma.Networking
|
||||
if (sentOffset == 0)
|
||||
{
|
||||
// first message; send length, chunk length and file name
|
||||
message = connection.Peer.CreateMessage(sendBytes + 8);
|
||||
message = connection.Peer.CreateMessage(sendBytes + 8 + 1);
|
||||
message.Write((byte)PacketTypes.FileStream);
|
||||
message.Write((byte)FileTransferMessageType.Initiate);
|
||||
message.Write((byte)fileType);
|
||||
message.Write((ulong)inputStream.Length);
|
||||
message.Write(Path.GetFileName(inputStream.Name));
|
||||
connection.SendMessage(message, NetDeliveryMethod.ReliableOrdered, 1);
|
||||
@@ -78,22 +144,44 @@ namespace Barotrauma.Networking
|
||||
Status = FileTransferStatus.Sending;
|
||||
}
|
||||
|
||||
message = connection.Peer.CreateMessage(sendBytes + 8);
|
||||
message = connection.Peer.CreateMessage(sendBytes + 8 + 1);
|
||||
message.Write((byte)PacketTypes.FileStream);
|
||||
message.Write((byte)fileType);
|
||||
message.Write(tempBuffer, 0, sendBytes);
|
||||
|
||||
connection.SendMessage(message, NetDeliveryMethod.ReliableOrdered, 1);
|
||||
sentOffset += sendBytes;
|
||||
|
||||
waitTimer = connection.AverageRoundtripTime;
|
||||
|
||||
//Program.Output("Sent " + m_sentOffset + "/" + m_inputStream.Length + " bytes to " + m_connection);
|
||||
|
||||
if (remaining - sendBytes <= 0)
|
||||
{
|
||||
inputStream.Close();
|
||||
inputStream.Dispose();
|
||||
inputStream = null;
|
||||
//Dispose();
|
||||
|
||||
Status = FileTransferStatus.Finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CancelTransfer()
|
||||
{
|
||||
Status = FileTransferStatus.Canceled;
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
inputStream.Close();
|
||||
inputStream.Dispose();
|
||||
inputStream = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using Microsoft.Xna.Framework;
|
||||
using System.Collections.Generic;
|
||||
using Barotrauma.Networking.ReliableMessages;
|
||||
using FarseerPhysics;
|
||||
using System.IO;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
@@ -15,6 +16,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
private ReliableChannel reliableChannel;
|
||||
|
||||
private FileStreamReceiver fileStreamReceiver;
|
||||
|
||||
private GUITickBox endRoundButton;
|
||||
|
||||
private bool connected;
|
||||
@@ -35,6 +38,11 @@ namespace Barotrauma.Networking
|
||||
get { return otherClients; }
|
||||
}
|
||||
|
||||
public string ActiveFileTransferName
|
||||
{
|
||||
get { return (fileStreamReceiver == null || fileStreamReceiver.Status == FileTransferStatus.Finished) ? "" : fileStreamReceiver.FileName; }
|
||||
}
|
||||
|
||||
public GameClient(string newName)
|
||||
{
|
||||
endRoundButton = new GUITickBox(new Rectangle(GameMain.GraphicsWidth - 170, 20, 20, 20), "End round", Alignment.TopLeft, inGameHUD);
|
||||
@@ -99,7 +107,7 @@ namespace Barotrauma.Networking
|
||||
NetOutgoingMessage outmsg = client.CreateMessage();
|
||||
client.Start();
|
||||
|
||||
outmsg.WriteEnum(PacketTypes.Login);
|
||||
outmsg.Write((byte)PacketTypes.Login);
|
||||
outmsg.Write(myID);
|
||||
outmsg.Write(password);
|
||||
outmsg.Write(GameMain.Version.ToString());
|
||||
@@ -221,7 +229,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
// All manually sent messages are type of "Data"
|
||||
case NetIncomingMessageType.Data:
|
||||
byte packetType = (byte)inc.ReadEnum<PacketTypes>();
|
||||
byte packetType = inc.ReadByte();
|
||||
if (packetType == (byte)PacketTypes.LoggedIn)
|
||||
{
|
||||
myID = inc.ReadByte();
|
||||
@@ -262,7 +270,7 @@ namespace Barotrauma.Networking
|
||||
CanStart = true;
|
||||
|
||||
NetOutgoingMessage lobbyUpdateRequest = client.CreateMessage();
|
||||
lobbyUpdateRequest.WriteEnum(PacketTypes.RequestNetLobbyUpdate);
|
||||
lobbyUpdateRequest.Write((byte)PacketTypes.RequestNetLobbyUpdate);
|
||||
client.SendMessage(lobbyUpdateRequest, NetDeliveryMethod.ReliableUnordered);
|
||||
}
|
||||
else if (packetType == (byte)PacketTypes.KickedOut)
|
||||
@@ -445,12 +453,12 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (inc.MessageType != NetIncomingMessageType.Data) continue;
|
||||
|
||||
byte packetType = (byte)inc.ReadEnum<PacketTypes>();
|
||||
byte packetType = inc.ReadByte();
|
||||
|
||||
if (packetType == (byte)PacketTypes.ReliableMessage)
|
||||
{
|
||||
if (!reliableChannel.CheckMessage(inc)) continue;
|
||||
packetType = (byte)inc.ReadEnum<PacketTypes>();
|
||||
packetType = inc.ReadByte();
|
||||
}
|
||||
|
||||
switch (packetType)
|
||||
@@ -474,6 +482,35 @@ namespace Barotrauma.Networking
|
||||
|
||||
AddChatMessage(otherClient.name + " has joined the server", ChatMessageType.Server);
|
||||
|
||||
break;
|
||||
case (byte)PacketTypes.RequestFile:
|
||||
bool accepted = inc.ReadBoolean();
|
||||
|
||||
if (!accepted)
|
||||
{
|
||||
new GUIMessageBox("File transfer canceled", inc.ReadString());
|
||||
|
||||
if (fileStreamReceiver!=null)
|
||||
{
|
||||
fileStreamReceiver.DeleteFile();
|
||||
fileStreamReceiver.Dispose();
|
||||
fileStreamReceiver = null;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case (byte)PacketTypes.FileStream:
|
||||
if (fileStreamReceiver == null)
|
||||
{
|
||||
//todo: unexpected file
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
fileStreamReceiver.ReadMessage(inc);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case (byte)PacketTypes.PlayerLeft:
|
||||
byte leavingID = inc.ReadByte();
|
||||
@@ -510,7 +547,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
break;
|
||||
case (byte)PacketTypes.Chatmessage:
|
||||
ChatMessageType messageType = inc.ReadEnum<ChatMessageType>();
|
||||
ChatMessageType messageType = (ChatMessageType)inc.ReadByte();
|
||||
|
||||
AddChatMessage(inc.ReadString(), messageType);
|
||||
break;
|
||||
@@ -678,6 +715,23 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
base.Draw(spriteBatch);
|
||||
|
||||
if (fileStreamReceiver != null &&
|
||||
(fileStreamReceiver.Status == FileTransferStatus.Receiving || fileStreamReceiver.Status == FileTransferStatus.NotStarted))
|
||||
{
|
||||
Vector2 pos = Screen.Selected == GameMain.NetLobbyScreen ?
|
||||
new Vector2(GameMain.NetLobbyScreen.SubList.Rect.X, GameMain.NetLobbyScreen.SubList.Rect.Bottom+5) : new Vector2(GameMain.GraphicsWidth / 2 - 200, 10);
|
||||
|
||||
GUI.DrawString(spriteBatch, pos, "Downloading " + fileStreamReceiver.FileName, Color.White);
|
||||
GUI.DrawString(spriteBatch, pos + Vector2.UnitX*300,
|
||||
MathUtils.GetBytesReadable((long)fileStreamReceiver.Received) + " / " + MathUtils.GetBytesReadable((long)fileStreamReceiver.FileSize), Color.White);
|
||||
GUI.DrawProgressBar(spriteBatch, new Vector2(pos.X, -pos.Y - 20), new Vector2(300, 15), fileStreamReceiver.Progress, Color.Green);
|
||||
|
||||
if (GUI.DrawButton(spriteBatch, new Rectangle((int)pos.X + 310, (int)pos.Y + 20, 100, 15), "Cancel", new Color(0.88f, 0.25f, 0.15f, 0.8f)))
|
||||
{
|
||||
CancelFileTransfer();
|
||||
}
|
||||
}
|
||||
|
||||
if (!GameMain.DebugDraw) return;
|
||||
|
||||
int width = 200, height = 300;
|
||||
@@ -691,24 +745,78 @@ namespace Barotrauma.Networking
|
||||
|
||||
spriteBatch.DrawString(GUI.SmallFont, "Sent bytes: " + client.Statistics.SentBytes, new Vector2(x + 10, y + 75), Color.White);
|
||||
spriteBatch.DrawString(GUI.SmallFont, "Sent packets: " + client.Statistics.SentPackets, new Vector2(x + 10, y + 90), Color.White);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override void Disconnect()
|
||||
{
|
||||
NetOutgoingMessage msg = client.CreateMessage();
|
||||
msg.WriteEnum(PacketTypes.PlayerLeft);
|
||||
msg.Write((byte)PacketTypes.PlayerLeft);
|
||||
|
||||
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||
client.Shutdown("");
|
||||
GameMain.NetworkMember = null;
|
||||
}
|
||||
|
||||
public void RequestFile(string file, FileTransferMessageType fileType)
|
||||
{
|
||||
if (fileStreamReceiver!=null)
|
||||
{
|
||||
CancelFileTransfer();
|
||||
}
|
||||
|
||||
NetOutgoingMessage msg = client.CreateMessage();
|
||||
msg.Write((byte)PacketTypes.RequestFile);
|
||||
msg.Write((byte)fileType);
|
||||
|
||||
msg.Write(file);
|
||||
|
||||
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||
|
||||
fileStreamReceiver = new FileStreamReceiver(client, Path.Combine(Submarine.SavePath, "Downloaded"), fileType, OnFileReceived);
|
||||
}
|
||||
|
||||
private void OnFileReceived(FileStreamReceiver receiver)
|
||||
{
|
||||
if (receiver.Status == FileTransferStatus.Error)
|
||||
{
|
||||
new GUIMessageBox("Error while receiving file from server", receiver.ErrorMessage, 400, 350);
|
||||
receiver.DeleteFile();
|
||||
|
||||
}
|
||||
else if (receiver.Status == FileTransferStatus.Finished)
|
||||
{
|
||||
new GUIMessageBox("Download finished", "File ''" + receiver.FileName + "'' was downloaded succesfully.");
|
||||
|
||||
switch (receiver.FileType)
|
||||
{
|
||||
case FileTransferMessageType.Submarine:
|
||||
Submarine.Preload();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fileStreamReceiver = null;
|
||||
}
|
||||
|
||||
private void CancelFileTransfer()
|
||||
{
|
||||
fileStreamReceiver.DeleteFile();
|
||||
fileStreamReceiver.Dispose();
|
||||
fileStreamReceiver = null;
|
||||
|
||||
NetOutgoingMessage msg = client.CreateMessage();
|
||||
msg.Write((byte)PacketTypes.RequestFile);
|
||||
msg.Write((byte)FileTransferMessageType.Cancel);
|
||||
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||
}
|
||||
|
||||
public void Vote(VoteType voteType, object userData)
|
||||
{
|
||||
NetOutgoingMessage msg = client.CreateMessage();
|
||||
msg.WriteEnum(PacketTypes.Vote);
|
||||
msg.WriteEnum(voteType);
|
||||
msg.Write((byte)PacketTypes.Vote);
|
||||
msg.Write((byte)voteType);
|
||||
|
||||
switch (voteType)
|
||||
{
|
||||
@@ -729,7 +837,7 @@ namespace Barotrauma.Networking
|
||||
public bool SpectateClicked(GUIButton button, object userData)
|
||||
{
|
||||
NetOutgoingMessage msg = client.CreateMessage();
|
||||
msg.WriteEnum(PacketTypes.SpectateRequest);
|
||||
msg.Write((byte)PacketTypes.SpectateRequest);
|
||||
|
||||
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||
|
||||
@@ -760,7 +868,7 @@ namespace Barotrauma.Networking
|
||||
if (characterInfo == null) return;
|
||||
|
||||
NetOutgoingMessage msg = client.CreateMessage();
|
||||
msg.WriteEnum(PacketTypes.CharacterInfo);
|
||||
msg.Write((byte)PacketTypes.CharacterInfo);
|
||||
|
||||
msg.Write(characterInfo.Name);
|
||||
msg.Write(characterInfo.Gender == Gender.Male);
|
||||
@@ -837,8 +945,8 @@ namespace Barotrauma.Networking
|
||||
(myCharacter == null || myCharacter.IsDead)) ? ChatMessageType.Dead : ChatMessageType.Default;
|
||||
|
||||
ReliableMessage msg = reliableChannel.CreateMessage();
|
||||
msg.InnerMessage.WriteEnum(PacketTypes.Chatmessage);
|
||||
msg.InnerMessage.WriteEnum(type);
|
||||
msg.InnerMessage.Write((byte)PacketTypes.Chatmessage);
|
||||
msg.InnerMessage.Write((byte)type);
|
||||
msg.InnerMessage.Write(message);
|
||||
|
||||
reliableChannel.SendMessage(msg, client.ServerConnection);
|
||||
@@ -848,41 +956,41 @@ namespace Barotrauma.Networking
|
||||
/// sends some random data to the server (can be a networkevent or just something completely random)
|
||||
/// use for debugging purposes
|
||||
/// </summary>
|
||||
public void SendRandomData()
|
||||
{
|
||||
NetOutgoingMessage msg = client.CreateMessage();
|
||||
switch (Rand.Int(5))
|
||||
{
|
||||
case 0:
|
||||
msg.WriteEnum(PacketTypes.NetworkEvent);
|
||||
msg.WriteEnum(NetworkEventType.EntityUpdate);
|
||||
msg.Write(Rand.Int(MapEntity.mapEntityList.Count));
|
||||
break;
|
||||
case 1:
|
||||
msg.WriteEnum(PacketTypes.NetworkEvent);
|
||||
msg.Write((byte)Enum.GetNames(typeof(NetworkEventType)).Length);
|
||||
msg.Write(Rand.Int(MapEntity.mapEntityList.Count));
|
||||
break;
|
||||
case 2:
|
||||
msg.WriteEnum(PacketTypes.NetworkEvent);
|
||||
msg.WriteEnum(NetworkEventType.ComponentUpdate);
|
||||
msg.Write((int)Item.ItemList[Rand.Int(Item.ItemList.Count)].ID);
|
||||
msg.Write(Rand.Int(8));
|
||||
break;
|
||||
case 3:
|
||||
msg.Write((byte)Enum.GetNames(typeof(PacketTypes)).Length);
|
||||
break;
|
||||
}
|
||||
//public void SendRandomData()
|
||||
//{
|
||||
// NetOutgoingMessage msg = client.CreateMessage();
|
||||
// switch (Rand.Int(5))
|
||||
// {
|
||||
// case 0:
|
||||
// msg.WriteEnum(PacketTypes.NetworkEvent);
|
||||
// msg.WriteEnum(NetworkEventType.EntityUpdate);
|
||||
// msg.Write(Rand.Int(MapEntity.mapEntityList.Count));
|
||||
// break;
|
||||
// case 1:
|
||||
// msg.WriteEnum(PacketTypes.NetworkEvent);
|
||||
// msg.Write((byte)Enum.GetNames(typeof(NetworkEventType)).Length);
|
||||
// msg.Write(Rand.Int(MapEntity.mapEntityList.Count));
|
||||
// break;
|
||||
// case 2:
|
||||
// msg.WriteEnum(PacketTypes.NetworkEvent);
|
||||
// msg.WriteEnum(NetworkEventType.ComponentUpdate);
|
||||
// msg.Write((int)Item.ItemList[Rand.Int(Item.ItemList.Count)].ID);
|
||||
// msg.Write(Rand.Int(8));
|
||||
// break;
|
||||
// case 3:
|
||||
// msg.Write((byte)Enum.GetNames(typeof(PacketTypes)).Length);
|
||||
// break;
|
||||
// }
|
||||
|
||||
int bitCount = Rand.Int(100);
|
||||
for (int i = 0; i<bitCount; i++)
|
||||
{
|
||||
msg.Write(Rand.Int(2)==0);
|
||||
}
|
||||
// int bitCount = Rand.Int(100);
|
||||
// for (int i = 0; i<bitCount; i++)
|
||||
// {
|
||||
// msg.Write(Rand.Int(2)==0);
|
||||
// }
|
||||
|
||||
|
||||
client.SendMessage(msg, (Rand.Int(2)==0) ? NetDeliveryMethod.ReliableOrdered : NetDeliveryMethod.Unreliable);
|
||||
}
|
||||
// client.SendMessage(msg, (Rand.Int(2)==0) ? NetDeliveryMethod.ReliableOrdered : NetDeliveryMethod.Unreliable);
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace Barotrauma.Networking
|
||||
private DateTime sparseUpdateTimer;
|
||||
private DateTime refreshMasterTimer;
|
||||
|
||||
private RestClient restClient;
|
||||
private bool masterServerResponded;
|
||||
|
||||
private ServerLog log;
|
||||
@@ -96,6 +97,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
banList = new BanList();
|
||||
|
||||
LoadSettings();
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
|
||||
@@ -160,17 +163,21 @@ namespace Barotrauma.Networking
|
||||
|
||||
private void RegisterToMasterServer()
|
||||
{
|
||||
var client = new RestClient(NetConfig.MasterServerUrl);
|
||||
if (restClient==null)
|
||||
{
|
||||
restClient = new RestClient(NetConfig.MasterServerUrl);
|
||||
}
|
||||
|
||||
var request = new RestRequest("masterserver.php", Method.GET);
|
||||
var request = new RestRequest("masterserver2.php", Method.GET);
|
||||
request.AddParameter("action", "addserver");
|
||||
request.AddParameter("servername", name);
|
||||
request.AddParameter("serverport", Port);
|
||||
request.AddParameter("playercount", PlayerCountToByte(ConnectedClients.Count, config.MaximumConnections));
|
||||
request.AddParameter("currplayers", ConnectedClients.Count);
|
||||
request.AddParameter("maxplayers", config.MaximumConnections);
|
||||
request.AddParameter("password", string.IsNullOrWhiteSpace(password) ? 0 : 1);
|
||||
|
||||
// execute the request
|
||||
RestResponse response = (RestResponse)client.Execute(request);
|
||||
RestResponse response = (RestResponse)restClient.Execute(request);
|
||||
|
||||
if (response.StatusCode != System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
@@ -190,12 +197,16 @@ namespace Barotrauma.Networking
|
||||
|
||||
private IEnumerable<object> RefreshMaster()
|
||||
{
|
||||
var client = new RestClient(NetConfig.MasterServerUrl);
|
||||
if (restClient == null)
|
||||
{
|
||||
restClient = new RestClient(NetConfig.MasterServerUrl);
|
||||
}
|
||||
|
||||
var request = new RestRequest("masterserver.php", Method.GET);
|
||||
var request = new RestRequest("masterserver2.php", Method.GET);
|
||||
request.AddParameter("action", "refreshserver");
|
||||
request.AddParameter("gamestarted", gameStarted ? 1 : 0);
|
||||
request.AddParameter("playercount", PlayerCountToByte(ConnectedClients.Count, config.MaximumConnections));
|
||||
request.AddParameter("currplayers", ConnectedClients.Count);
|
||||
request.AddParameter("maxplayers", config.MaximumConnections);
|
||||
|
||||
Log("Refreshing connection with master server...", Color.Cyan);
|
||||
|
||||
@@ -203,7 +214,7 @@ namespace Barotrauma.Networking
|
||||
sw.Start();
|
||||
|
||||
masterServerResponded = false;
|
||||
var restRequestHandle = client.ExecuteAsync(request, response => MasterServerCallBack(response));
|
||||
var restRequestHandle = restClient.ExecuteAsync(request, response => MasterServerCallBack(response));
|
||||
|
||||
DateTime timeOut = DateTime.Now + new TimeSpan(0, 0, 15);
|
||||
while (!masterServerResponded)
|
||||
@@ -310,6 +321,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
foreach (Client c in ConnectedClients)
|
||||
{
|
||||
if (c.FileStreamSender != null) UpdateFileTransfer(c, deltaTime);
|
||||
|
||||
c.ReliableChannel.Update(deltaTime);
|
||||
}
|
||||
|
||||
@@ -420,7 +433,7 @@ namespace Barotrauma.Networking
|
||||
// Notify the client that they have logged in
|
||||
var outmsg = server.CreateMessage();
|
||||
|
||||
outmsg.WriteEnum(PacketTypes.LoggedIn);
|
||||
outmsg.Write((byte)PacketTypes.LoggedIn);
|
||||
outmsg.Write(sender.ID);
|
||||
outmsg.Write(gameStarted);
|
||||
outmsg.Write(gameStarted && sender.Character!=null);
|
||||
@@ -445,7 +458,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
//notify other clients about the new client
|
||||
outmsg = server.CreateMessage();
|
||||
outmsg.WriteEnum(PacketTypes.PlayerJoined);
|
||||
outmsg.Write((byte)PacketTypes.PlayerJoined);
|
||||
outmsg.Write(sender.name);
|
||||
outmsg.Write(sender.ID);
|
||||
|
||||
@@ -474,12 +487,12 @@ namespace Barotrauma.Networking
|
||||
Client dataSender = ConnectedClients.Find(c => c.Connection == inc.SenderConnection);
|
||||
if (dataSender == null) return;
|
||||
|
||||
byte packetType = (byte)inc.ReadEnum<PacketTypes>();
|
||||
byte packetType = inc.ReadByte();
|
||||
|
||||
if (packetType == (byte)PacketTypes.ReliableMessage)
|
||||
{
|
||||
if (!dataSender.ReliableChannel.CheckMessage(inc)) return;
|
||||
packetType = (byte)inc.ReadEnum<PacketTypes>();
|
||||
packetType = inc.ReadByte();
|
||||
}
|
||||
|
||||
switch (packetType)
|
||||
@@ -490,7 +503,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
break;
|
||||
case (byte)PacketTypes.Chatmessage:
|
||||
ChatMessageType messageType = inc.ReadEnum<ChatMessageType>();
|
||||
ChatMessageType messageType = (ChatMessageType)inc.ReadByte();
|
||||
|
||||
SendChatMessage(inc.ReadString(), messageType);
|
||||
|
||||
@@ -500,6 +513,48 @@ namespace Barotrauma.Networking
|
||||
break;
|
||||
case (byte)PacketTypes.CharacterInfo:
|
||||
ReadCharacterData(inc);
|
||||
break;
|
||||
case (byte)PacketTypes.RequestFile:
|
||||
|
||||
if (!allowFileTransfers)
|
||||
{
|
||||
SendCancelTransferMessage(dataSender, "File transfers have been disabled by the server.");
|
||||
break;
|
||||
}
|
||||
|
||||
byte fileType = inc.ReadByte();
|
||||
string fileName = fileType == (byte)FileTransferMessageType.Cancel ? "" : inc.ReadString();
|
||||
|
||||
switch (fileType)
|
||||
{
|
||||
case (byte)FileTransferMessageType.Submarine:
|
||||
|
||||
var requestedSubmarine = Submarine.SavedSubmarines.Find(s => s.Name == fileName);
|
||||
|
||||
if (requestedSubmarine==null)
|
||||
{
|
||||
//todo: ei voi ladata
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dataSender.FileStreamSender != null) dataSender.FileStreamSender.CancelTransfer();
|
||||
|
||||
var fileStreamSender = FileStreamSender.Create(dataSender.Connection, requestedSubmarine.FilePath, FileTransferMessageType.Submarine);
|
||||
if (fileStreamSender != null) dataSender.FileStreamSender = fileStreamSender;
|
||||
}
|
||||
break;
|
||||
case (byte)FileTransferMessageType.Cancel:
|
||||
if (dataSender.FileStreamSender != null)
|
||||
{
|
||||
dataSender.FileStreamSender.CancelTransfer();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DebugConsole.ThrowError("Unknown file type was requested ("+fileType+")");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case (byte)PacketTypes.ResendRequest:
|
||||
|
||||
@@ -511,11 +566,11 @@ namespace Barotrauma.Networking
|
||||
case (byte)PacketTypes.Vote:
|
||||
Voting.RegisterVote(inc, ConnectedClients);
|
||||
|
||||
if (Voting.AllowEndVoting && EndVoteMax > 0 &&
|
||||
if (Voting.AllowEndVoting && EndVoteMax > 0 &&
|
||||
((float)EndVoteCount / (float)EndVoteMax) >= EndVoteRequiredRatio)
|
||||
{
|
||||
Log("Ending round by votes ("+EndVoteCount+"/"+(EndVoteMax-EndVoteCount)+")", Color.Cyan);
|
||||
EndButtonHit(null,null);
|
||||
Log("Ending round by votes (" + EndVoteCount + "/" + (EndVoteMax - EndVoteCount) + ")", Color.Cyan);
|
||||
EndButtonHit(null, null);
|
||||
}
|
||||
break;
|
||||
case (byte)PacketTypes.RequestNetLobbyUpdate:
|
||||
@@ -541,7 +596,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
private void HandleConnectionApproval(NetIncomingMessage inc)
|
||||
{
|
||||
if (inc.ReadEnum<PacketTypes>() != PacketTypes.Login) return;
|
||||
if ((PacketTypes)inc.ReadByte() != PacketTypes.Login) return;
|
||||
|
||||
DebugConsole.NewMessage("New player has joined the server", Color.White);
|
||||
|
||||
@@ -649,6 +704,8 @@ namespace Barotrauma.Networking
|
||||
UpdateCrewFrame();
|
||||
|
||||
inc.SenderConnection.Approve();
|
||||
|
||||
refreshMasterTimer = DateTime.Now;
|
||||
}
|
||||
|
||||
|
||||
@@ -789,6 +846,14 @@ namespace Barotrauma.Networking
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (ConnectedClients.Any(c => c.FileStreamSender != null && c.FileStreamSender.FilePath == selectedSub.FilePath))
|
||||
{
|
||||
new GUIMessageBox("Couldn't start a round",
|
||||
"Can't start a round while sending the selected submarine to clients. Cancel the transfers or wait for them to finish before starting.", 400, 400);
|
||||
return false;
|
||||
}
|
||||
|
||||
GameMain.ShowLoading(StartGame(selectedSub, selectedMode), false);
|
||||
|
||||
return true;
|
||||
@@ -877,7 +942,6 @@ namespace Barotrauma.Networking
|
||||
|
||||
GameMain.GameScreen.Select();
|
||||
|
||||
|
||||
AddChatMessage("Press TAB to chat. Use ''d;'' to talk to dead players and spectators, and ''player name;'' to only send the message to a specific player.", ChatMessageType.Server);
|
||||
|
||||
yield return CoroutineStatus.Success;
|
||||
@@ -886,7 +950,7 @@ namespace Barotrauma.Networking
|
||||
private NetOutgoingMessage CreateStartMessage(int seed, Submarine selectedSub, GameModePreset selectedMode)
|
||||
{
|
||||
NetOutgoingMessage msg = server.CreateMessage();
|
||||
msg.WriteEnum(PacketTypes.StartGame);
|
||||
msg.Write((byte)PacketTypes.StartGame);
|
||||
|
||||
msg.Write(seed);
|
||||
|
||||
@@ -910,7 +974,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (myCharacter != null)
|
||||
{
|
||||
msg.Write(0);
|
||||
msg.Write((byte)0);
|
||||
WriteCharacterData(msg, myCharacter.Info.Name, myCharacter);
|
||||
}
|
||||
|
||||
@@ -949,7 +1013,7 @@ namespace Barotrauma.Networking
|
||||
if (ConnectedClients.Count > 0)
|
||||
{
|
||||
NetOutgoingMessage msg = server.CreateMessage();
|
||||
msg.WriteEnum(PacketTypes.EndGame);
|
||||
msg.Write((byte)PacketTypes.EndGame);
|
||||
msg.Write(endMessage);
|
||||
|
||||
if (server.ConnectionsCount > 0)
|
||||
@@ -989,7 +1053,9 @@ namespace Barotrauma.Networking
|
||||
private void DisconnectClient(NetConnection senderConnection, string msg = "", string targetmsg = "")
|
||||
{
|
||||
Client client = ConnectedClients.Find(x => x.Connection == senderConnection);
|
||||
if (client != null) DisconnectClient(client, msg, targetmsg);
|
||||
if (client == null) return;
|
||||
|
||||
DisconnectClient(client, msg, targetmsg);
|
||||
}
|
||||
|
||||
private void DisconnectClient(Client client, string msg = "", string targetmsg = "")
|
||||
@@ -1007,14 +1073,14 @@ namespace Barotrauma.Networking
|
||||
Log(msg, messageColor[(int)ChatMessageType.Server]);
|
||||
|
||||
NetOutgoingMessage outmsg = server.CreateMessage();
|
||||
outmsg.WriteEnum(PacketTypes.KickedOut);
|
||||
outmsg.Write((byte)PacketTypes.KickedOut);
|
||||
outmsg.Write(targetmsg);
|
||||
server.SendMessage(outmsg, client.Connection, NetDeliveryMethod.ReliableUnordered, 0);
|
||||
|
||||
ConnectedClients.Remove(client);
|
||||
|
||||
outmsg = server.CreateMessage();
|
||||
outmsg.WriteEnum(PacketTypes.PlayerLeft);
|
||||
outmsg.Write((byte)PacketTypes.PlayerLeft);
|
||||
outmsg.Write(client.ID);
|
||||
outmsg.Write(msg);
|
||||
|
||||
@@ -1025,9 +1091,17 @@ namespace Barotrauma.Networking
|
||||
server.SendMessage(outmsg, server.Connections, NetDeliveryMethod.ReliableUnordered, 0);
|
||||
}
|
||||
|
||||
if (client.FileStreamSender != null)
|
||||
{
|
||||
client.FileStreamSender.Dispose();
|
||||
client.FileStreamSender = null;
|
||||
}
|
||||
|
||||
AddChatMessage(msg, ChatMessageType.Server);
|
||||
|
||||
UpdateCrewFrame();
|
||||
|
||||
refreshMasterTimer = DateTime.Now;
|
||||
}
|
||||
|
||||
private void UpdateCrewFrame()
|
||||
@@ -1073,6 +1147,65 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateFileTransfer(Client client, float deltaTime)
|
||||
{
|
||||
if (client.FileStreamSender == null) return;
|
||||
|
||||
var clientNameBox = GameMain.NetLobbyScreen.PlayerList.FindChild(client.name);
|
||||
var clientInfo = clientNameBox.FindChild(client.FileStreamSender);
|
||||
|
||||
if (clientInfo == null)
|
||||
{
|
||||
clientNameBox.ClearChildren();
|
||||
|
||||
clientInfo = new GUIFrame(new Rectangle(0, 0, 180, 0), Color.Transparent, Alignment.TopRight, null, clientNameBox);
|
||||
clientInfo.UserData = client.FileStreamSender;
|
||||
new GUIProgressBar(new Rectangle(0, 4, 160, clientInfo.Rect.Height - 8), Color.Green, GUI.Style, 0.0f, Alignment.Left, clientInfo).IsHorizontal = true;
|
||||
new GUITextBlock(new Rectangle(0, 2, 160, 0), "", GUI.Style, Alignment.TopLeft, Alignment.Left | Alignment.CenterY, clientInfo, true, GUI.SmallFont);
|
||||
|
||||
var cancelButton = new GUIButton(new Rectangle(20, 0, 14, 0), "X", Alignment.Right, GUI.Style, clientInfo);
|
||||
cancelButton.OnClicked = (GUIButton button, object userdata) =>
|
||||
{
|
||||
(cancelButton.Parent.UserData as FileStreamSender).CancelTransfer();
|
||||
return true;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
var progressBar = clientInfo.GetChild<GUIProgressBar>();
|
||||
progressBar.BarSize = client.FileStreamSender.Progress;
|
||||
|
||||
var progressText = clientInfo.GetChild<GUITextBlock>();
|
||||
progressText.Text = client.FileStreamSender.FileName + " " +
|
||||
MathUtils.GetBytesReadable(client.FileStreamSender.Sent) + " / " + MathUtils.GetBytesReadable(client.FileStreamSender.FileSize);
|
||||
}
|
||||
|
||||
client.FileStreamSender.Update(deltaTime);
|
||||
|
||||
if (client.FileStreamSender.Status != FileTransferStatus.Sending &&
|
||||
client.FileStreamSender.Status != FileTransferStatus.NotStarted)
|
||||
{
|
||||
if (client.FileStreamSender.Status == FileTransferStatus.Canceled)
|
||||
{
|
||||
SendCancelTransferMessage(client, "File transfer was canceled by the server.");
|
||||
}
|
||||
|
||||
clientNameBox.RemoveChild(clientInfo);
|
||||
|
||||
client.FileStreamSender.Dispose();
|
||||
client.FileStreamSender = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void SendCancelTransferMessage(Client client, string message)
|
||||
{
|
||||
var outmsg = server.CreateMessage();
|
||||
outmsg.Write((byte)PacketTypes.RequestFile);
|
||||
outmsg.Write(false);
|
||||
outmsg.Write(message);
|
||||
server.SendMessage(outmsg, client.Connection, NetDeliveryMethod.ReliableUnordered);
|
||||
}
|
||||
|
||||
public void NewTraitor(Character traitor, Character target)
|
||||
{
|
||||
Log(traitor.Name + " is the traitor and the target is " + target.Name, Color.Cyan);
|
||||
@@ -1086,7 +1219,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
NetOutgoingMessage msg = server.CreateMessage();
|
||||
msg.WriteEnum(PacketTypes.Traitor);
|
||||
msg.Write((byte)PacketTypes.Traitor);
|
||||
msg.Write(target.Info.Name);
|
||||
if (server.Connections.Count > 0)
|
||||
{
|
||||
@@ -1175,7 +1308,7 @@ namespace Barotrauma.Networking
|
||||
try
|
||||
{
|
||||
NetOutgoingMessage msg = server.CreateMessage();
|
||||
msg.WriteEnum(PacketTypes.VoteStatus);
|
||||
msg.Write((byte)PacketTypes.VoteStatus);
|
||||
Voting.WriteData(msg, ConnectedClients);
|
||||
|
||||
server.SendMessage(msg, server.Connections, NetDeliveryMethod.ReliableUnordered, 0);
|
||||
@@ -1199,7 +1332,7 @@ namespace Barotrauma.Networking
|
||||
if (server.Connections.Count == 0) return true;
|
||||
|
||||
NetOutgoingMessage msg = server.CreateMessage();
|
||||
msg.WriteEnum(PacketTypes.UpdateNetLobby);
|
||||
msg.Write((byte)PacketTypes.UpdateNetLobby);
|
||||
GameMain.NetLobbyScreen.WriteData(msg);
|
||||
|
||||
server.SendMessage(msg, server.Connections, NetDeliveryMethod.ReliableUnordered, 0);
|
||||
@@ -1275,8 +1408,8 @@ namespace Barotrauma.Networking
|
||||
foreach (Client c in recipients)
|
||||
{
|
||||
ReliableMessage msg = c.ReliableChannel.CreateMessage();
|
||||
msg.InnerMessage.WriteEnum(PacketTypes.Chatmessage);
|
||||
msg.InnerMessage.WriteEnum(type);
|
||||
msg.InnerMessage.Write((byte)PacketTypes.Chatmessage);
|
||||
msg.InnerMessage.Write((byte)type);
|
||||
msg.InnerMessage.Write(message);
|
||||
|
||||
c.ReliableChannel.SendMessage(msg, c.Connection);
|
||||
@@ -1343,7 +1476,7 @@ namespace Barotrauma.Networking
|
||||
if (items == null || !items.Any()) return;
|
||||
|
||||
NetOutgoingMessage message = server.CreateMessage();
|
||||
message.WriteEnum(PacketTypes.NewItem);
|
||||
message.Write((byte)PacketTypes.NewItem);
|
||||
|
||||
Item.Spawner.FillNetworkData(message, items, inventories);
|
||||
|
||||
@@ -1466,13 +1599,13 @@ namespace Barotrauma.Networking
|
||||
switch (Rand.Int(5))
|
||||
{
|
||||
case 0:
|
||||
msg.WriteEnum(PacketTypes.NetworkEvent);
|
||||
msg.Write(Rand.Int(Enum.GetNames(typeof(NetworkEventType)).Length));
|
||||
msg.Write(Rand.Int(MapEntity.mapEntityList.Count));
|
||||
msg.Write((byte)PacketTypes.NetworkEvent);
|
||||
msg.Write((byte)Rand.Int(Enum.GetNames(typeof(NetworkEventType)).Length));
|
||||
msg.Write((ushort)Rand.Int(MapEntity.mapEntityList.Count));
|
||||
break;
|
||||
case 1:
|
||||
msg.WriteEnum(PacketTypes.NetworkEvent);
|
||||
msg.WriteEnum(NetworkEventType.ComponentUpdate);
|
||||
msg.Write((byte)PacketTypes.NetworkEvent);
|
||||
msg.Write((byte)NetworkEventType.ComponentUpdate);
|
||||
msg.Write((int)Item.ItemList[Rand.Int(Item.ItemList.Count)].ID);
|
||||
msg.Write(Rand.Int(8));
|
||||
break;
|
||||
@@ -1497,12 +1630,27 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
banList.Save();
|
||||
|
||||
|
||||
if (registeredToMaster && restClient != null)
|
||||
{
|
||||
var request = new RestRequest("masterserver2.php", Method.GET);
|
||||
request.AddParameter("action", "removeserver");
|
||||
|
||||
restClient.Execute(request);
|
||||
restClient = null;
|
||||
}
|
||||
|
||||
if (saveServerLogs)
|
||||
{
|
||||
Log("Shutting down server...", Color.Cyan);
|
||||
log.Save();
|
||||
}
|
||||
|
||||
foreach (Client client in ConnectedClients)
|
||||
{
|
||||
if (client.FileStreamSender != null) client.FileStreamSender.Dispose();
|
||||
}
|
||||
|
||||
server.Shutdown("The server has shut down");
|
||||
}
|
||||
}
|
||||
@@ -1523,6 +1671,8 @@ namespace Barotrauma.Networking
|
||||
public List<JobPrefab> jobPreferences;
|
||||
public JobPrefab assignedJob;
|
||||
|
||||
public FileStreamSender FileStreamSender;
|
||||
|
||||
public bool Spectating;
|
||||
|
||||
public ReliableChannel ReliableChannel;
|
||||
|
||||
@@ -3,6 +3,8 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
@@ -18,6 +20,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
partial class GameServer : NetworkMember
|
||||
{
|
||||
public const string SettingsFile = "serversettings.xml";
|
||||
|
||||
public bool ShowNetStats;
|
||||
|
||||
private TimeSpan refreshMasterInterval = new TimeSpan(0, 0, 30);
|
||||
@@ -45,6 +49,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
private bool saveServerLogs = true;
|
||||
|
||||
private bool allowFileTransfers = true;
|
||||
|
||||
public bool AutoRestart
|
||||
{
|
||||
get { return (ConnectedClients.Count == 0) ? false : autoRestart; }
|
||||
@@ -89,15 +95,112 @@ namespace Barotrauma.Networking
|
||||
|
||||
public float EndVoteRequiredRatio = 0.5f;
|
||||
|
||||
private void SaveSettings()
|
||||
{
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
settings.Indent = true;
|
||||
settings.NewLineOnAttributes = true;
|
||||
|
||||
using (var writer = XmlWriter.Create(SettingsFile, settings))
|
||||
{
|
||||
writer.WriteStartElement("serversettings");
|
||||
writer.WriteAttributeString("AllowSpectating", allowSpectating.ToString());
|
||||
writer.WriteAttributeString("RandomizeSeed", randomizeSeed.ToString());
|
||||
|
||||
writer.WriteAttributeString("EndRoundAtLevelEnd", endRoundAtLevelEnd.ToString());
|
||||
writer.WriteAttributeString("AllowFileTransfers", allowFileTransfers.ToString());
|
||||
writer.WriteAttributeString("MaxFileTransferDuration", ((int)FileStreamSender.MaxTransferDuration.TotalSeconds).ToString());
|
||||
writer.WriteAttributeString("SaveServerLogs", saveServerLogs.ToString());
|
||||
writer.WriteAttributeString("LinesPerLogFile", log.LinesPerFile.ToString());
|
||||
writer.WriteAttributeString("SubSelection", subSelectionMode.ToString());
|
||||
writer.WriteAttributeString("ModeSelection", modeSelectionMode.ToString());
|
||||
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadSettings()
|
||||
{
|
||||
XDocument doc = null;
|
||||
if (System.IO.File.Exists(SettingsFile))
|
||||
{
|
||||
doc = ToolBox.TryLoadXml(SettingsFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (doc == null)
|
||||
{
|
||||
doc = new XDocument(new XElement("serversettings"));
|
||||
}
|
||||
|
||||
allowSpectating = ToolBox.GetAttributeBool(doc.Root, "AllowSpectating", true);
|
||||
randomizeSeed = ToolBox.GetAttributeBool(doc.Root, "RandomizeSeed", true);
|
||||
endRoundAtLevelEnd = ToolBox.GetAttributeBool(doc.Root, "EndRoundAtLevelEnd", true);
|
||||
allowFileTransfers = ToolBox.GetAttributeBool(doc.Root, "AllowFileTransfers", true);
|
||||
|
||||
saveServerLogs = ToolBox.GetAttributeBool(doc.Root, "SaveServerLogs", true);
|
||||
log.LinesPerFile = ToolBox.GetAttributeInt(doc.Root, "LinesPerLogFile", 800);
|
||||
|
||||
subSelectionMode = SelectionMode.Manual;
|
||||
Enum.TryParse<SelectionMode>(ToolBox.GetAttributeString(doc.Root, "SubSelection", "Manual"), out subSelectionMode);
|
||||
|
||||
modeSelectionMode = SelectionMode.Manual;
|
||||
Enum.TryParse<SelectionMode>(ToolBox.GetAttributeString(doc.Root, "ModeSelection", "Manual"), out modeSelectionMode);
|
||||
|
||||
FileStreamSender.MaxTransferDuration = new TimeSpan(0,0,ToolBox.GetAttributeInt(doc.Root, "MaxFileTransferDuration", 150));
|
||||
}
|
||||
|
||||
private void CreateSettingsFrame()
|
||||
{
|
||||
settingsFrame = new GUIFrame(new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Black * 0.5f);
|
||||
|
||||
|
||||
GUIFrame innerFrame = new GUIFrame(new Rectangle(0, 0, 400, 400), null, Alignment.Center, GUI.Style, settingsFrame);
|
||||
innerFrame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
|
||||
|
||||
new GUITextBlock(new Rectangle(0, -15, 0, 20), "Server settings", GUI.Style, innerFrame, GUI.LargeFont);
|
||||
new GUITextBlock(new Rectangle(0, -5, 0, 20), "Server settings", GUI.Style, innerFrame, GUI.LargeFont);
|
||||
|
||||
var randomizeLevelBox = new GUITickBox(new Rectangle(0, 30, 20, 20), "Randomize level seed between rounds", Alignment.Left, innerFrame);
|
||||
int y = 40;
|
||||
|
||||
var endBox = new GUITickBox(new Rectangle(0, y, 20, 20), "End round when destination reached", Alignment.Left, innerFrame);
|
||||
endBox.Selected = endRoundAtLevelEnd;
|
||||
endBox.OnSelected = (GUITickBox) => { endRoundAtLevelEnd = GUITickBox.Selected; return true; };
|
||||
|
||||
|
||||
y += 30;
|
||||
var endVoteBox = new GUITickBox(new Rectangle(0, y, 20, 20), "End round by voting", Alignment.Left, innerFrame);
|
||||
endVoteBox.Selected = Voting.AllowEndVoting;
|
||||
endVoteBox.OnSelected = (GUITickBox) =>
|
||||
{
|
||||
Voting.AllowEndVoting = !Voting.AllowEndVoting;
|
||||
GameMain.Server.UpdateVoteStatus();
|
||||
return true;
|
||||
};
|
||||
|
||||
var votesRequiredText = new GUITextBlock(new Rectangle(20, y+20, 20, 20), "Votes required: 50 %", GUI.Style, innerFrame, GUI.SmallFont);
|
||||
|
||||
var votesRequiredSlider = new GUIScrollBar(new Rectangle(150, y+22, 100, 10), GUI.Style, 0.1f, innerFrame);
|
||||
votesRequiredSlider.UserData = votesRequiredText;
|
||||
votesRequiredSlider.BarScroll = (EndVoteRequiredRatio - 0.5f) * 2.0f;
|
||||
votesRequiredSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
GUITextBlock voteText = scrollBar.UserData as GUITextBlock;
|
||||
|
||||
scrollBar.BarScroll = MathUtils.Round(barScroll, 0.2f);
|
||||
EndVoteRequiredRatio = barScroll / 2.0f + 0.5f;
|
||||
voteText.Text = "Votes required: " + (int)MathUtils.Round(EndVoteRequiredRatio * 100.0f, 10.0f) + " %";
|
||||
return true;
|
||||
};
|
||||
votesRequiredSlider.OnMoved(votesRequiredSlider, votesRequiredSlider.BarScroll);
|
||||
|
||||
y += 40;
|
||||
|
||||
|
||||
|
||||
var randomizeLevelBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Randomize level seed between rounds", Alignment.Left, innerFrame);
|
||||
randomizeLevelBox.Selected = randomizeSeed;
|
||||
randomizeLevelBox.OnSelected = (GUITickBox) =>
|
||||
{
|
||||
@@ -105,37 +208,23 @@ namespace Barotrauma.Networking
|
||||
return true;
|
||||
};
|
||||
|
||||
var endBox = new GUITickBox(new Rectangle(0, 60, 20, 20), "End round when destination reached", Alignment.Left, innerFrame);
|
||||
endBox.Selected = endRoundAtLevelEnd;
|
||||
endBox.OnSelected = (GUITickBox) => { endRoundAtLevelEnd = GUITickBox.Selected; return true; };
|
||||
|
||||
var endVoteBox = new GUITickBox(new Rectangle(0, 90, 20, 20), "End round by voting", Alignment.Left, innerFrame);
|
||||
endVoteBox.Selected = Voting.AllowEndVoting;
|
||||
endVoteBox.OnSelected = (GUITickBox) =>
|
||||
y += 40;
|
||||
|
||||
var shareSubsBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Share submarine files with players", Alignment.Left, innerFrame);
|
||||
shareSubsBox.Selected = allowFileTransfers;
|
||||
shareSubsBox.OnSelected = (GUITickBox) =>
|
||||
{
|
||||
Voting.AllowEndVoting = !Voting.AllowEndVoting;
|
||||
GameMain.Server.UpdateVoteStatus();
|
||||
return true;
|
||||
};
|
||||
|
||||
var votesRequiredText = new GUITextBlock(new Rectangle(20, 110, 20, 20), "Votes required: 50 %", GUI.Style, innerFrame, GUI.SmallFont);
|
||||
|
||||
var votesRequiredSlider = new GUIScrollBar(new Rectangle(150,115, 100, 10), GUI.Style, 0.1f, innerFrame);
|
||||
votesRequiredSlider.UserData = votesRequiredText;
|
||||
votesRequiredSlider.BarScroll = (EndVoteRequiredRatio - 0.5f) * 2.0f;
|
||||
votesRequiredSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
GUITextBlock voteText = scrollBar.UserData as GUITextBlock;
|
||||
|
||||
scrollBar.BarScroll = MathUtils.Round(barScroll, 0.2f);
|
||||
EndVoteRequiredRatio = barScroll/2.0f + 0.5f;
|
||||
voteText.Text = "Votes required: " + (int)MathUtils.Round(EndVoteRequiredRatio * 100.0f, 10.0f) + " %";
|
||||
allowFileTransfers = GUITickBox.Selected;
|
||||
return true;
|
||||
};
|
||||
votesRequiredSlider.OnMoved(votesRequiredSlider, votesRequiredSlider.BarScroll);
|
||||
|
||||
new GUITextBlock(new Rectangle(0, 95+50, 100, 20), "Submarine selection:", GUI.Style, innerFrame);
|
||||
var selectionFrame = new GUIFrame(new Rectangle(0, 120 + 50, 300, 20), null, innerFrame);
|
||||
|
||||
y += 40;
|
||||
|
||||
|
||||
new GUITextBlock(new Rectangle(0, y, 100, 20), "Submarine selection:", GUI.Style, innerFrame);
|
||||
var selectionFrame = new GUIFrame(new Rectangle(0, y+20, 300, 20), null, innerFrame);
|
||||
for (int i = 0; i<3; i++)
|
||||
{
|
||||
var selectionTick = new GUITickBox(new Rectangle(i * 100, 0, 20, 20), ((SelectionMode)i).ToString(), Alignment.Left, selectionFrame);
|
||||
@@ -144,8 +233,10 @@ namespace Barotrauma.Networking
|
||||
selectionTick.UserData = (SelectionMode)i;
|
||||
}
|
||||
|
||||
new GUITextBlock(new Rectangle(0, 145 + 50, 100, 20), "Mode selection:", GUI.Style, innerFrame);
|
||||
selectionFrame = new GUIFrame(new Rectangle(0, 170 + 50, 300, 20), null, innerFrame);
|
||||
y += 45;
|
||||
|
||||
new GUITextBlock(new Rectangle(0, y, 100, 20), "Mode selection:", GUI.Style, innerFrame);
|
||||
selectionFrame = new GUIFrame(new Rectangle(0, y+20, 300, 20), null, innerFrame);
|
||||
for (int i = 0; i<3; i++)
|
||||
{
|
||||
var selectionTick = new GUITickBox(new Rectangle(i*100, 0, 20, 20), ((SelectionMode)i).ToString(), Alignment.Left, selectionFrame);
|
||||
@@ -154,7 +245,9 @@ namespace Barotrauma.Networking
|
||||
selectionTick.UserData = (SelectionMode)i;
|
||||
}
|
||||
|
||||
var allowSpecBox = new GUITickBox(new Rectangle(0, 210 + 50, 20, 20), "Allow spectating", Alignment.Left, innerFrame);
|
||||
y += 60;
|
||||
|
||||
var allowSpecBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Allow spectating", Alignment.Left, innerFrame);
|
||||
allowSpecBox.Selected = allowSpectating;
|
||||
allowSpecBox.OnSelected = (GUITickBox) =>
|
||||
{
|
||||
@@ -162,7 +255,9 @@ namespace Barotrauma.Networking
|
||||
return true;
|
||||
};
|
||||
|
||||
var saveLogsBox = new GUITickBox(new Rectangle(0, 240 + 50, 20, 20), "Save server logs", Alignment.Left, innerFrame);
|
||||
y += 30;
|
||||
|
||||
var saveLogsBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Save server logs", Alignment.Left, innerFrame);
|
||||
saveLogsBox.Selected = saveServerLogs;
|
||||
saveLogsBox.OnSelected = (GUITickBox) =>
|
||||
{
|
||||
@@ -225,6 +320,7 @@ namespace Barotrauma.Networking
|
||||
else
|
||||
{
|
||||
settingsFrame = null;
|
||||
SaveSettings();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -5,14 +5,14 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
static class NetBufferExtensions
|
||||
{
|
||||
public static void WriteEnum(this NetBuffer buffer, Enum value)
|
||||
{
|
||||
buffer.WriteRangedInteger(0, Enum.GetValues(value.GetType()).Length - 1, Convert.ToInt32(value));
|
||||
}
|
||||
//public static void WriteEnum(this NetBuffer buffer, Enum value)
|
||||
//{
|
||||
// buffer.WriteRangedInteger(0, Enum.GetValues(value.GetType()).Length - 1, Convert.ToInt32(value));
|
||||
//}
|
||||
|
||||
public static TEnum ReadEnum<TEnum>(this NetBuffer buffer)
|
||||
{
|
||||
return (TEnum)(object)buffer.ReadRangedInteger(0, Enum.GetValues(typeof(TEnum)).Length - 1);
|
||||
}
|
||||
//public static TEnum ReadEnum<TEnum>(this NetBuffer buffer)
|
||||
//{
|
||||
// return (TEnum)(object)buffer.ReadRangedInteger(0, Enum.GetValues(typeof(TEnum)).Length - 1);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
public bool FillData(NetBuffer message)
|
||||
{
|
||||
message.WriteEnum(eventType);
|
||||
message.Write((byte)eventType);
|
||||
|
||||
Entity e = Entity.FindEntityByID(id);
|
||||
if (e == null) return false;
|
||||
@@ -189,7 +189,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
try
|
||||
{
|
||||
eventType = message.ReadEnum<NetworkEventType>();
|
||||
eventType = (NetworkEventType)message.ReadByte();
|
||||
id = message.ReadUInt16();
|
||||
}
|
||||
catch (Exception exception)
|
||||
|
||||
@@ -7,7 +7,7 @@ using Lidgren.Network;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
enum PacketTypes : int
|
||||
enum PacketTypes : byte
|
||||
{
|
||||
Unknown,
|
||||
|
||||
@@ -32,6 +32,8 @@ namespace Barotrauma.Networking
|
||||
Vote, VoteStatus,
|
||||
|
||||
ResendRequest, ReliableMessage, LatestMessageID,
|
||||
|
||||
RequestFile, FileStream,
|
||||
|
||||
SpectateRequest
|
||||
}
|
||||
@@ -163,14 +165,14 @@ namespace Barotrauma.Networking
|
||||
if (msgBytes.Count == 0) return null;
|
||||
|
||||
NetOutgoingMessage message = netPeer.CreateMessage();
|
||||
message.WriteEnum(PacketTypes.NetworkEvent);
|
||||
message.Write((byte)PacketTypes.NetworkEvent);
|
||||
|
||||
message.Write((float)NetTime.Now);
|
||||
|
||||
message.Write((byte)msgBytes.Count);
|
||||
foreach (byte[] msgData in msgBytes)
|
||||
{
|
||||
if (msgData.Length > 255) DebugConsole.ThrowError("too large networkevent (" + msgData.Length + " bytes)");
|
||||
if (msgData.Length > 255) DebugConsole.ThrowError("Too large networkevent (" + msgData.Length + " bytes)");
|
||||
|
||||
message.Write((byte)msgData.Length);
|
||||
message.Write(msgData);
|
||||
@@ -295,25 +297,6 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
public virtual void Disconnect() { }
|
||||
|
||||
protected byte PlayerCountToByte(int playerCount, int maxPlayers)
|
||||
{
|
||||
byte byteVal = (byte)playerCount;
|
||||
|
||||
byteVal |= (byte)((maxPlayers - 1) << 4);
|
||||
|
||||
return byteVal;
|
||||
}
|
||||
|
||||
public static int ByteToPlayerCount(byte byteVal, out int maxPlayers)
|
||||
{
|
||||
maxPlayers = (byteVal >> 4)+1;
|
||||
|
||||
int playerCount = byteVal & (byte)((1 << 4) - 1);
|
||||
|
||||
return playerCount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace Barotrauma.Networking.ReliableMessages
|
||||
|
||||
var reliableMessage = new ReliableMessage(message, messageID);
|
||||
|
||||
message.WriteEnum(PacketTypes.ReliableMessage);
|
||||
message.Write((byte)PacketTypes.ReliableMessage);
|
||||
|
||||
message.Write(messageID);
|
||||
|
||||
@@ -184,7 +184,7 @@ namespace Barotrauma.Networking.ReliableMessages
|
||||
//Debug.WriteLine("Sending ack message: "+messageCount);
|
||||
|
||||
NetOutgoingMessage message = sender.CreateMessage();
|
||||
message.WriteEnum(PacketTypes.LatestMessageID);
|
||||
message.Write((byte)PacketTypes.LatestMessageID);
|
||||
|
||||
message.Write(messageCount);
|
||||
|
||||
@@ -244,7 +244,7 @@ namespace Barotrauma.Networking.ReliableMessages
|
||||
Debug.WriteLine("rerequest "+missingMessage.ID+" (try #"+missingMessage.ResendRequestsSent+")");
|
||||
|
||||
NetOutgoingMessage resendRequest = receiver.CreateMessage();
|
||||
resendRequest.WriteEnum(PacketTypes.ResendRequest);
|
||||
resendRequest.Write((byte)PacketTypes.ResendRequest);
|
||||
|
||||
resendRequest.Write(missingMessage.ID);
|
||||
|
||||
@@ -443,6 +443,7 @@ namespace Barotrauma.Networking.ReliableMessages
|
||||
|
||||
public void SaveInnerMessage()
|
||||
{
|
||||
innerMessage.WritePadBits();
|
||||
innerMessageBytes = innerMessage.PeekBytes(innerMessage.LengthBytes);
|
||||
//innerMessage = null;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
class ServerLog
|
||||
{
|
||||
const int LinesPerFile = 300;
|
||||
private int linesPerFile = 800;
|
||||
|
||||
public const string SavePath = "ServerLogs";
|
||||
|
||||
@@ -21,6 +21,12 @@ namespace Barotrauma.Networking
|
||||
|
||||
private Queue<ColoredText> lines;
|
||||
|
||||
public int LinesPerFile
|
||||
{
|
||||
get { return linesPerFile; }
|
||||
set { linesPerFile = Math.Max(10, linesPerFile); }
|
||||
}
|
||||
|
||||
public ServerLog(string serverName)
|
||||
{
|
||||
this.serverName = serverName;
|
||||
|
||||
@@ -155,24 +155,28 @@ namespace Barotrauma
|
||||
if (held) heldQueue = true;
|
||||
}
|
||||
|
||||
public bool Dequeue
|
||||
public bool DequeueHit()
|
||||
{
|
||||
get
|
||||
{
|
||||
bool value = hitQueue;
|
||||
hitQueue = false;
|
||||
return value;
|
||||
}
|
||||
bool value = hitQueue;
|
||||
hitQueue = false;
|
||||
return value;
|
||||
}
|
||||
|
||||
public bool DequeueHeld
|
||||
public bool DequeueHeld()
|
||||
{
|
||||
get
|
||||
{
|
||||
bool value = heldQueue;
|
||||
heldQueue = false;
|
||||
return value;
|
||||
}
|
||||
bool value = heldQueue;
|
||||
heldQueue = false;
|
||||
return value;
|
||||
}
|
||||
|
||||
public bool GetHeldQueue
|
||||
{
|
||||
get { return heldQueue; }
|
||||
}
|
||||
|
||||
public bool GetHitQueue
|
||||
{
|
||||
get { return hitQueue; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -193,7 +193,7 @@ namespace Barotrauma
|
||||
return editableProperties;
|
||||
}
|
||||
|
||||
public static Dictionary<string, ObjectProperty> GetProperties(object obj)
|
||||
public static Dictionary<string, ObjectProperty> GetProperties(IPropertyObject obj)
|
||||
{
|
||||
var properties = TypeDescriptor.GetProperties(obj.GetType()).Cast<PropertyDescriptor>();
|
||||
|
||||
@@ -207,7 +207,12 @@ namespace Barotrauma
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
public static Dictionary<string, ObjectProperty> InitProperties(object obj, XElement element)
|
||||
public static Dictionary<string, ObjectProperty> InitProperties(IPropertyObject obj)
|
||||
{
|
||||
return InitProperties(obj, null);
|
||||
}
|
||||
|
||||
public static Dictionary<string, ObjectProperty> InitProperties(IPropertyObject obj, XElement element)
|
||||
{
|
||||
var properties = TypeDescriptor.GetProperties(obj.GetType()).Cast<PropertyDescriptor>();
|
||||
|
||||
@@ -226,16 +231,19 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
//go through all the attributes in the xml element
|
||||
//and set the value of the matching property if it is initializable
|
||||
foreach (XAttribute attribute in element.Attributes())
|
||||
if (element!=null)
|
||||
{
|
||||
ObjectProperty property = null;
|
||||
if (!dictionary.TryGetValue(attribute.Name.ToString().ToLower(), out property)) continue;
|
||||
if (!property.Attributes.OfType<HasDefaultValue>().Any()) continue;
|
||||
property.TrySetValue(attribute.Value);
|
||||
//go through all the attributes in the xml element
|
||||
//and set the value of the matching property if it is initializable
|
||||
foreach (XAttribute attribute in element.Attributes())
|
||||
{
|
||||
ObjectProperty property = null;
|
||||
if (!dictionary.TryGetValue(attribute.Name.ToString().ToLower(), out property)) continue;
|
||||
if (!property.Attributes.OfType<HasDefaultValue>().Any()) continue;
|
||||
property.TrySetValue(attribute.Value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
@@ -291,7 +292,14 @@ namespace Barotrauma
|
||||
return false;
|
||||
}
|
||||
|
||||
Submarine.SaveCurrent(nameBox.Text + ".sub");
|
||||
string savePath = nameBox.Text + ".sub";
|
||||
|
||||
if (Submarine.Loaded != null)
|
||||
{
|
||||
savePath = Path.Combine(Path.GetDirectoryName(Submarine.Loaded.FilePath), savePath);
|
||||
}
|
||||
|
||||
Submarine.SaveCurrent(savePath);
|
||||
Submarine.Loaded.CheckForErrors();
|
||||
|
||||
GUI.AddMessage("Submarine saved to " + Submarine.Loaded.FilePath, Color.Green, 3.0f);
|
||||
|
||||
@@ -177,7 +177,7 @@ namespace Barotrauma
|
||||
//{
|
||||
// cam.TargetPos = Character.Controlled.WorldPosition;
|
||||
//}
|
||||
|
||||
|
||||
cam.UpdateTransform();
|
||||
|
||||
DrawMap(graphics, spriteBatch);
|
||||
@@ -200,6 +200,8 @@ namespace Barotrauma
|
||||
|
||||
if (GameMain.GameSession != null) GameMain.GameSession.Draw(spriteBatch);
|
||||
|
||||
if (Character.Controlled == null && Submarine.Loaded != null) DrawSubmarineIndicator(spriteBatch, Submarine.Loaded);
|
||||
|
||||
GUI.Draw((float)deltaTime, spriteBatch, cam);
|
||||
|
||||
if (!PlayerInput.LeftButtonHeld()) Inventory.draggingItem = null;
|
||||
@@ -348,5 +350,25 @@ namespace Barotrauma
|
||||
|
||||
GameMain.LightManager.DrawLOS(graphics, spriteBatch, cam);
|
||||
}
|
||||
|
||||
private void DrawSubmarineIndicator(SpriteBatch spriteBatch, Submarine submarine)
|
||||
{
|
||||
Vector2 subDiff = submarine.WorldPosition - cam.Position;
|
||||
|
||||
if (Math.Abs(subDiff.X) > cam.WorldView.Width || Math.Abs(subDiff.Y) > cam.WorldView.Height)
|
||||
{
|
||||
Vector2 normalizedSubDiff = Vector2.Normalize(subDiff);
|
||||
|
||||
Vector2 iconPos =
|
||||
cam.WorldToScreen(cam.Position) +
|
||||
new Vector2(normalizedSubDiff.X * GameMain.GraphicsWidth * 0.4f, -normalizedSubDiff.Y * GameMain.GraphicsHeight * 0.4f);
|
||||
|
||||
GUI.SubmarineIcon.Draw(spriteBatch, iconPos, Color.LightBlue * 0.5f);
|
||||
|
||||
Vector2 arrowOffset = normalizedSubDiff * GUI.SubmarineIcon.size.X * 0.7f;
|
||||
arrowOffset.Y = -arrowOffset.Y;
|
||||
GUI.Arrow.Draw(spriteBatch, iconPos + arrowOffset, Color.LightBlue * 0.5f, MathUtils.VectorToAngle(arrowOffset) + MathHelper.PiOver2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,10 @@ namespace Barotrauma
|
||||
public bool IsServer;
|
||||
public string ServerName, ServerMessage;
|
||||
|
||||
const float NetworkUpdateInterval = 1.0f;
|
||||
private float networkUpdateTimer;
|
||||
private bool valueChanged;
|
||||
|
||||
private Sprite backgroundSprite;
|
||||
|
||||
private GUITextBox serverMessage;
|
||||
@@ -51,6 +55,11 @@ namespace Barotrauma
|
||||
get { return modeList; }
|
||||
}
|
||||
|
||||
public GUIListBox PlayerList
|
||||
{
|
||||
get { return playerList; }
|
||||
}
|
||||
|
||||
public GUIFrame InfoFrame
|
||||
{
|
||||
get { return infoFrame; }
|
||||
@@ -183,24 +192,7 @@ namespace Barotrauma
|
||||
voteText.UserData = "subvotes";
|
||||
voteText.Visible = false;
|
||||
|
||||
if (Submarine.SavedSubmarines.Count > 0)
|
||||
{
|
||||
foreach (Submarine sub in Submarine.SavedSubmarines)
|
||||
{
|
||||
GUITextBlock textBlock = new GUITextBlock(
|
||||
new Rectangle(0, 0, 0, 25),
|
||||
sub.Name, GUI.Style,
|
||||
Alignment.Left, Alignment.Left,
|
||||
subList);
|
||||
textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f);
|
||||
textBlock.UserData = sub;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError("No saved submarines found!");
|
||||
return;
|
||||
}
|
||||
UpdateSubList();
|
||||
|
||||
columnX += columnWidth + 20;
|
||||
|
||||
@@ -209,8 +201,7 @@ namespace Barotrauma
|
||||
new GUITextBlock(new Rectangle(columnX, 120, 0, 30), "Game mode: ", GUI.Style, infoFrame);
|
||||
modeList = new GUIListBox(new Rectangle(columnX, 150, columnWidth, infoFrame.Rect.Height - 150 - 80), GUI.Style, infoFrame);
|
||||
modeList.OnSelected = VotableClicked;
|
||||
|
||||
|
||||
|
||||
voteText = new GUITextBlock(new Rectangle(columnX, 120, columnWidth, 30), "Votes: ", GUI.Style, Alignment.TopLeft, Alignment.TopRight, infoFrame);
|
||||
voteText.UserData = "modevotes";
|
||||
voteText.Visible = false;
|
||||
@@ -327,7 +318,7 @@ namespace Barotrauma
|
||||
modeList.OnSelected = VotableClicked;
|
||||
modeList.OnSelected = SelectMode;
|
||||
subList.OnSelected = VotableClicked;
|
||||
subList.OnSelected = SelectMap;
|
||||
subList.OnSelected = SelectSub;
|
||||
|
||||
traitorProbabilityButtons[0].OnClicked = ToggleTraitorsEnabled;
|
||||
traitorProbabilityButtons[1].OnClicked = ToggleTraitorsEnabled;
|
||||
@@ -449,8 +440,6 @@ namespace Barotrauma
|
||||
|
||||
UpdateJobPreferences(jobList);
|
||||
|
||||
//UpdatePreviewPlayer(Game1.Client.CharacterInfo);
|
||||
|
||||
UpdatePreviewPlayer(characterInfo);
|
||||
}
|
||||
}
|
||||
@@ -484,8 +473,8 @@ namespace Barotrauma
|
||||
if (GameMain.Server == null) return false;
|
||||
|
||||
GameMain.Server.AutoRestart = tickBox.Selected;
|
||||
|
||||
GameMain.Server.UpdateNetLobby(tickBox);
|
||||
|
||||
valueChanged = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -501,8 +490,8 @@ namespace Barotrauma
|
||||
if (index > 2) index = 0;
|
||||
|
||||
SetTraitorsEnabled((YesNoMaybe)index);
|
||||
|
||||
if (GameMain.Server != null) GameMain.Server.UpdateNetLobby(null);
|
||||
|
||||
valueChanged = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -515,20 +504,51 @@ namespace Barotrauma
|
||||
|
||||
}
|
||||
|
||||
private bool SelectMap(GUIComponent component, object obj)
|
||||
private bool SelectSub(GUIComponent component, object obj)
|
||||
{
|
||||
if (GameMain.Server != null) GameMain.Server.UpdateNetLobby(obj);
|
||||
valueChanged = true;
|
||||
|
||||
//Submarine sub = (Submarine)obj;
|
||||
var hash = (obj as Submarine).MD5Hash;
|
||||
|
||||
//hash will be null if opening the sub file failed -> don't select the sub
|
||||
if (string.IsNullOrWhiteSpace(hash.Hash))
|
||||
{
|
||||
(component as GUITextBlock).TextColor = Color.DarkRed * 0.8f;
|
||||
component.CanBeFocused = false;
|
||||
|
||||
//submarine already loaded
|
||||
//if (Submarine.Loaded != null && sub.FilePath == Submarine.Loaded.FilePath) return true;
|
||||
|
||||
//sub.Load();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void UpdateSubList()
|
||||
{
|
||||
if (subList == null) return;
|
||||
|
||||
subList.ClearChildren();
|
||||
|
||||
if (Submarine.SavedSubmarines.Count > 0)
|
||||
{
|
||||
foreach (Submarine sub in Submarine.SavedSubmarines)
|
||||
{
|
||||
GUITextBlock textBlock = new GUITextBlock(
|
||||
new Rectangle(0, 0, 0, 25),
|
||||
sub.Name, GUI.Style,
|
||||
Alignment.Left, Alignment.Left,
|
||||
subList);
|
||||
textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f);
|
||||
textBlock.UserData = sub;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError("No saved submarines found!");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public bool VotableClicked(GUIComponent component, object userData)
|
||||
{
|
||||
if (GameMain.Client == null) return false;
|
||||
@@ -558,7 +578,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (GameMain.Server == null) return false;
|
||||
ServerName = text;
|
||||
GameMain.Server.UpdateNetLobby(null, null);
|
||||
valueChanged = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -567,7 +587,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (GameMain.Server == null) return false;
|
||||
ServerMessage = text;
|
||||
GameMain.Server.UpdateNetLobby(null, null);
|
||||
valueChanged = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -575,7 +595,7 @@ namespace Barotrauma
|
||||
public void AddPlayer(string name)
|
||||
{
|
||||
GUITextBlock textBlock = new GUITextBlock(
|
||||
new Rectangle(0, 0, 0, 25), name,
|
||||
new Rectangle(0, 0, playerList.Rect.Width-20, 25), name,
|
||||
GUI.Style, Alignment.Left, Alignment.Left,
|
||||
playerList);
|
||||
|
||||
@@ -614,7 +634,7 @@ namespace Barotrauma
|
||||
var closeButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Close", Alignment.BottomRight, GUI.Style, playerFrameInner);
|
||||
closeButton.OnClicked = ClosePlayerFrame;
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool ClosePlayerFrame(GUIButton button, object userData)
|
||||
@@ -644,10 +664,7 @@ namespace Barotrauma
|
||||
|
||||
public void ClearPlayers()
|
||||
{
|
||||
for (int i = 1; i<playerList.CountChildren; i++)
|
||||
{
|
||||
playerList.RemoveChild(playerList.children[i]);
|
||||
}
|
||||
playerList.ClearChildren();
|
||||
}
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
@@ -692,6 +709,18 @@ namespace Barotrauma
|
||||
{
|
||||
if (GameMain.Server.BanList.BanFrame != null) GameMain.Server.BanList.BanFrame.Update((float)deltaTime);
|
||||
}
|
||||
|
||||
if (valueChanged && GameMain.Server != null)
|
||||
{
|
||||
networkUpdateTimer -= (float)deltaTime;
|
||||
if (networkUpdateTimer <= 0.0f)
|
||||
{
|
||||
GameMain.Server.UpdateNetLobby(null);
|
||||
|
||||
valueChanged = false;
|
||||
networkUpdateTimer = NetworkUpdateInterval;
|
||||
}
|
||||
}
|
||||
|
||||
//durationBar.BarScroll = Math.Max(durationBar.BarScroll, 1.0f / 60.0f);
|
||||
}
|
||||
@@ -803,7 +832,7 @@ namespace Barotrauma
|
||||
GameModePreset modePreset = obj as GameModePreset;
|
||||
if (modePreset == null) return false;
|
||||
|
||||
if (GameMain.Server != null) GameMain.Server.UpdateNetLobby(obj);
|
||||
valueChanged = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -818,8 +847,8 @@ namespace Barotrauma
|
||||
|
||||
//textBox.Text = LevelSeed;
|
||||
//textBox.Selected = false;
|
||||
|
||||
if (GameMain.Server != null) GameMain.Server.UpdateNetLobby(null);
|
||||
|
||||
valueChanged = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -901,29 +930,47 @@ namespace Barotrauma
|
||||
|
||||
public bool TrySelectSub(string subName, string md5Hash)
|
||||
{
|
||||
//already downloading the selected sub file
|
||||
if (GameMain.Client.ActiveFileTransferName == subName+".sub") return false;
|
||||
|
||||
Submarine sub = Submarine.SavedSubmarines.Find(m => m.Name == subName);
|
||||
if (sub == null)
|
||||
if (sub == null || sub.MD5Hash.Hash != md5Hash)
|
||||
{
|
||||
new GUIMessageBox("Submarine not found!","The submarine ''" + subName + "'' has been selected by the server. Matching file not found in your map folder.");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sub.MD5Hash.Hash != md5Hash)
|
||||
string errorMsg = "";
|
||||
if (sub == null)
|
||||
{
|
||||
new GUIMessageBox("Submarine not found!",
|
||||
"Your version of the map file ''" + sub.Name + "'' doesn't match the server's version!"
|
||||
+"\nYour file: " + sub.Name + "(MD5 hash : " + sub.MD5Hash.Hash + ")"
|
||||
+"\nServer's file: " + subName + "(MD5 hash : " + md5Hash + ")");
|
||||
return false;
|
||||
errorMsg = "Submarine ''" + subName + "'' was selected by the server. Matching file not found in your submarine folder. ";
|
||||
}
|
||||
else if (sub.MD5Hash.Hash == null)
|
||||
{
|
||||
errorMsg = "Couldn't load submarine ''" + subName + "''. The file may be corrupted. ";
|
||||
}
|
||||
else
|
||||
{
|
||||
subList.Select(sub, true);
|
||||
//map.Load();
|
||||
return true;
|
||||
errorMsg = "Your version of the submarine file ''" + sub.Name + "'' doesn't match the server's version! "
|
||||
+ "Your MD5 hash: " + sub.MD5Hash.Hash + " \n"
|
||||
+ "Server's MD5 hash: " + md5Hash + ". ";
|
||||
}
|
||||
|
||||
string downloadMsg = GameMain.Client.ActiveFileTransferName == "" ?
|
||||
"Do you want to download the file from the server host?" :
|
||||
"Do you want to download the file and cancel downloading ''" + GameMain.Client.ActiveFileTransferName + "''?";
|
||||
|
||||
var requestFileBox = new GUIMessageBox("Submarine not found!", errorMsg+downloadMsg, new string[] { "Yes", "No" }, 400, 300);
|
||||
requestFileBox.Buttons[0].UserData = subName;
|
||||
requestFileBox.Buttons[0].OnClicked += requestFileBox.Close;
|
||||
requestFileBox.Buttons[0].OnClicked += (GUIButton button, object userdata) =>
|
||||
{
|
||||
GameMain.Client.RequestFile(userdata.ToString(), FileTransferMessageType.Submarine);
|
||||
return true;
|
||||
};
|
||||
requestFileBox.Buttons[1].OnClicked += requestFileBox.Close;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
subList.Select(sub, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void WriteData(NetOutgoingMessage msg)
|
||||
@@ -949,7 +996,7 @@ namespace Barotrauma
|
||||
//msg.Write(AllowSubVoting);
|
||||
//msg.Write(AllowModeVoting);
|
||||
|
||||
msg.Write(modeList.SelectedIndex);
|
||||
msg.Write((byte)modeList.SelectedIndex);
|
||||
//msg.Write(durationBar.BarScroll);
|
||||
msg.Write(LevelSeed);
|
||||
|
||||
@@ -966,7 +1013,7 @@ namespace Barotrauma
|
||||
|
||||
public void ReadData(NetIncomingMessage msg)
|
||||
{
|
||||
string mapName="", md5Hash="";
|
||||
string mapName = "", md5Hash = "";
|
||||
|
||||
int modeIndex = 0;
|
||||
//float durationScroll = 0.0f;
|
||||
@@ -991,7 +1038,7 @@ namespace Barotrauma
|
||||
//AllowSubVoting = msg.ReadBoolean();
|
||||
//AllowModeVoting = msg.ReadBoolean();
|
||||
|
||||
modeIndex = msg.ReadInt32();
|
||||
modeIndex = msg.ReadByte();
|
||||
|
||||
//durationScroll = msg.ReadFloat();
|
||||
|
||||
@@ -1001,9 +1048,9 @@ namespace Barotrauma
|
||||
restartTimer = msg.ReadFloat();
|
||||
|
||||
int playerCount = msg.ReadByte();
|
||||
|
||||
|
||||
playerList.ClearChildren();
|
||||
for (int i = 0; i<playerCount; i++)
|
||||
for (int i = 0; i < playerCount; i++)
|
||||
{
|
||||
AddPlayer(msg.ReadString());
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ namespace Barotrauma
|
||||
voteText.UserData = "votes";
|
||||
}
|
||||
|
||||
voteText.Text = votes.ToString();
|
||||
voteText.Text = votes == 0 ? "" : votes.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,6 +233,11 @@ namespace Barotrauma
|
||||
AllowSubVoting = msg.ReadBoolean();
|
||||
if (allowSubVoting)
|
||||
{
|
||||
foreach (Submarine sub in Submarine.SavedSubmarines)
|
||||
{
|
||||
SetVoteText(GameMain.NetLobbyScreen.SubList, sub, 0);
|
||||
}
|
||||
|
||||
int votableCount = msg.ReadByte();
|
||||
for (int i = 0; i < votableCount; i++)
|
||||
{
|
||||
@@ -252,7 +257,7 @@ namespace Barotrauma
|
||||
int votes = msg.ReadByte();
|
||||
string modeName = msg.ReadString();
|
||||
GameModePreset mode = GameModePreset.list.Find(m => m.Name == modeName);
|
||||
SetVoteText(GameMain.NetLobbyScreen.SubList, mode, votes);
|
||||
SetVoteText(GameMain.NetLobbyScreen.ModeList, mode, votes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -165,24 +165,27 @@ namespace Barotrauma
|
||||
string port = arguments[1];
|
||||
string serverName = arguments[2];
|
||||
string gameStarted = (arguments.Length > 3) ? arguments[3] : "";
|
||||
string playerCountStr = (arguments.Length > 4) ? arguments[4] : "";
|
||||
string currPlayersStr = (arguments.Length > 4) ? arguments[4] : "";
|
||||
string maxPlayersStr = (arguments.Length > 5) ? arguments[5] : "";
|
||||
|
||||
string hasPassWordStr = (arguments.Length > 5) ? arguments[5] : "";
|
||||
|
||||
var serverFrame = new GUIFrame(new Rectangle(0,0,0,20), (i%2 == 0) ? Color.Transparent : Color.White*0.2f, null, serverList);
|
||||
serverFrame.UserData = IP+":"+port;
|
||||
string hasPassWordStr = (arguments.Length > 6) ? arguments[6] : "";
|
||||
|
||||
var serverFrame = new GUIFrame(new Rectangle(0, 0, 0, 20), (i % 2 == 0) ? Color.Transparent : Color.White * 0.2f, null, serverList);
|
||||
serverFrame.UserData = IP + ":" + port;
|
||||
serverFrame.HoverColor = Color.Gold * 0.2f;
|
||||
serverFrame.SelectedColor = Color.Gold * 0.5f;
|
||||
|
||||
var passwordBox = new GUITickBox(new Rectangle(columnX[0]/2, 0, 20, 20), "", Alignment.TopLeft, serverFrame);
|
||||
var passwordBox = new GUITickBox(new Rectangle(columnX[0] / 2, 0, 20, 20), "", Alignment.TopLeft, serverFrame);
|
||||
passwordBox.Selected = hasPassWordStr == "1";
|
||||
passwordBox.Enabled = false;
|
||||
passwordBox.UserData = "password";
|
||||
|
||||
var nameText = new GUITextBlock(new Rectangle(columnX[0], 0, 0, 0), serverName, GUI.Style, serverFrame);
|
||||
|
||||
int playerCount, maxPlayers;
|
||||
playerCount = GameClient.ByteToPlayerCount((byte)int.Parse(playerCountStr), out maxPlayers);
|
||||
int playerCount = 0, maxPlayers = 1;
|
||||
int.TryParse(currPlayersStr, out playerCount);
|
||||
int.TryParse(maxPlayersStr, out maxPlayers);
|
||||
|
||||
var playerCountText = new GUITextBlock(new Rectangle(columnX[1], 0, 0, 0), playerCount + "/" + maxPlayers, GUI.Style, serverFrame);
|
||||
|
||||
@@ -208,7 +211,7 @@ namespace Barotrauma
|
||||
if (client == null) yield return CoroutineStatus.Success;
|
||||
|
||||
|
||||
var request = new RestRequest("masterserver.php", Method.GET);
|
||||
var request = new RestRequest("masterserver2.php", Method.GET);
|
||||
request.AddParameter("gamename", "barotrauma"); // adds to POST or URL querystring based on Method
|
||||
request.AddParameter("action", "listservers"); // adds to POST or URL querystring based on Method
|
||||
|
||||
|
||||
Reference in New Issue
Block a user