Server list, lighting/los optimization

This commit is contained in:
Regalis
2015-08-07 23:10:12 +03:00
parent 08c5117e8f
commit 0937c30f15
45 changed files with 36611 additions and 41 deletions

View File

@@ -752,9 +752,14 @@ namespace Subsurface
public void DrawFront(SpriteBatch spriteBatch)
{
Vector2 pos = ConvertUnits.ToDisplayUnits(AnimController.limbs[0].SimPosition);
pos.Y = -pos.Y;
if (this == Character.controlled) return;
if (IsNetworkPlayer)
{
Vector2 namePos = new Vector2(Position.X, -Position.Y - 80.0f) - GUI.Font.MeasureString(Info.Name) * 0.5f;
Vector2 namePos = new Vector2(pos.X, pos.Y - 80.0f) - GUI.Font.MeasureString(Info.Name) * 0.5f;
spriteBatch.DrawString(GUI.Font, Info.Name, namePos - new Vector2(1.0f, 1.0f), Color.Black);
spriteBatch.DrawString(GUI.Font, Info.Name, namePos, Color.White);
@@ -764,11 +769,6 @@ namespace Subsurface
}
}
Vector2 pos = ConvertUnits.ToDisplayUnits(AnimController.limbs[0].SimPosition);
pos.Y = -pos.Y;
if (this == Character.controlled) return;
Vector2 healthBarPos = new Vector2(Position.X - 50, -Position.Y - 50.0f);
GUI.DrawRectangle(spriteBatch, new Rectangle((int)healthBarPos.X - 2, (int)healthBarPos.Y - 2, 100 + 4, 15 + 4), Color.Black, false);
GUI.DrawRectangle(spriteBatch, new Rectangle((int)healthBarPos.X, (int)healthBarPos.Y, (int)(100.0f * (health / maxHealth)), 15), Color.Red, true);

View File

@@ -9,6 +9,8 @@ namespace Subsurface
{
abstract class GUIComponent
{
const float FlashDuration = 1.5f;
public static GUIComponent MouseOn;
protected static KeyboardDispatcher keyboardDispatcher;
@@ -36,6 +38,8 @@ namespace Subsurface
protected ComponentState state;
protected float flashTimer;
public virtual SpriteFont Font
{
get;
@@ -200,12 +204,30 @@ namespace Subsurface
return false;
}
public void Flash()
{
flashTimer = FlashDuration;
foreach (GUIComponent child in children)
{
child.Flash();
}
}
public virtual void Draw(SpriteBatch spriteBatch)
{
Color currColor = color;
if (state == ComponentState.Selected) currColor = selectedColor;
if (state == ComponentState.Hover) currColor = hoverColor;
if (flashTimer>0.0f)
{
Color flashColor = Color.Red * (flashTimer / FlashDuration)*0.8f;
GUI.DrawRectangle(spriteBatch,
new Rectangle(rect.X-5,rect.Y-5,rect.Width+10,rect.Height+10), flashColor, true);
}
GUI.DrawRectangle(spriteBatch, rect, currColor * (currColor.A / 255.0f), true);
if (sprites != null)
@@ -246,6 +268,8 @@ namespace Subsurface
public virtual void Update(float deltaTime)
{
if (flashTimer>0.0f) flashTimer -= deltaTime;
if (CanBeFocused)
{
if (rect.Contains(PlayerInput.MousePosition))

View File

@@ -152,6 +152,7 @@ namespace Subsurface
MouseState previousMouse;
public override void Update(float deltaTime)
{
if (flashTimer > 0.0f) flashTimer -= deltaTime;
if (!Enabled) return;
caretTimer += deltaTime;
@@ -178,6 +179,8 @@ namespace Subsurface
}
}
textBlock.Update(deltaTime);
}
public override void Draw(SpriteBatch spriteBatch)

View File

@@ -30,7 +30,10 @@ namespace Subsurface
public static GameScreen GameScreen;
public static MainMenuScreen MainMenuScreen;
public static LobbyScreen LobbyScreen;
public static NetLobbyScreen NetLobbyScreen;
public static ServerListScreen ServerListScreen;
public static EditMapScreen EditMapScreen;
public static EditCharacterScreen EditCharacterScreen;
@@ -208,9 +211,13 @@ namespace Subsurface
MainMenuScreen = new MainMenuScreen(this);
LobbyScreen = new LobbyScreen();
NetLobbyScreen = new NetLobbyScreen();
ServerListScreen = new ServerListScreen();
EditMapScreen = new EditMapScreen();
EditCharacterScreen = new EditCharacterScreen();
yield return Status.Running;
ParticleManager = new ParticleManager("Content/Particles/ParticlePrefabs.xml", Cam);
@@ -298,9 +305,10 @@ namespace Subsurface
Screen.Selected.Draw(deltaTime, GraphicsDevice, spriteBatch);
}
if (sw.Elapsed.TotalSeconds < Physics.step)
double elapsed =sw.Elapsed.TotalSeconds;
if (elapsed < Physics.step)
{
System.Threading.Thread.Sleep((int)((Physics.step - sw.Elapsed.TotalSeconds)*1000.0));
System.Threading.Thread.Sleep((int)((Physics.step - elapsed) * 1000.0));
}
sw.Restart();
}

View File

@@ -14,6 +14,8 @@ namespace Subsurface
public string Name;
public bool IsSinglePlayer;
public string Description;
public GameModePreset(string name, Type type, bool isSinglePlayer = false)
{
this.Name = name;
@@ -145,10 +147,22 @@ namespace Subsurface
public static void Init()
{
new GameModePreset("Single Player", typeof(SinglePlayerMode), true);
var mode = new GameModePreset("SandBox", typeof(GameMode), false);
mode.Description = "A game mode with no specific objectives.";
mode = new GameModePreset("Traitor", typeof(TraitorMode), false);
mode.Description = "One of the players is selected as a traitor and given a secret objective. "
+ "The rest of the crew will win if they reach the end of the level or kill the traitor "
+ "before the objective is completed.";
mode = new GameModePreset("Quest", typeof(QuestMode), false);
mode.Description = "The crew must work together to complete a specific task, such as retrieving "
+ "an alien artifact or killing a creature that's terrorizing nearby outposts. The game ends "
+ "when the task is completed or everyone in the crew has died.";
new GameModePreset("SandBox", typeof(GameMode), false);
new GameModePreset("Traitor", typeof(TraitorMode), false);
new GameModePreset("Quest", typeof(QuestMode), false);
}
}
}

View File

@@ -31,6 +31,12 @@ namespace Subsurface
set;
}
public string MasterServerUrl
{
get;
private set;
}
public GameSettings(string filePath)
{
Load(filePath);
@@ -53,6 +59,9 @@ namespace Subsurface
GraphicsHeight = 768;
}
MasterServerUrl = ToolBox.GetAttributeString(doc.Root, "masterserverurl", "");
foreach (XElement subElement in doc.Root.Elements())
{
switch (subElement.Name.ToString().ToLower())

View File

@@ -17,27 +17,44 @@ namespace Subsurface.Lights
bool[] backFacing;
VertexPositionColor[] shadowVertices;
private Rectangle boundingBox;
public bool Enabled
{
get;
set;
}
public Rectangle BoundingBox
{
get { return boundingBox; }
}
public ConvexHull(Vector2[] points, Color color)
{
int vertexCount = points.Length;
vertices = new VertexPositionColor[vertexCount + 1];
Vector2 center = Vector2.Zero;
float? minX = null, minY = null, maxX = null, maxY = null;
for (int i = 0; i < vertexCount; i++)
{
vertices[i] = new VertexPositionColor(new Vector3(points[i], 0), color);
center += points[i];
if (minX == null || points[i].X < minX) minX = points[i].X;
if (minY == null || points[i].Y < minY) minY = points[i].Y;
if (maxX == null || points[i].X > maxX) maxX = points[i].X;
if (maxY == null || points[i].Y > minY) maxY = points[i].Y;
}
center /= points.Length;
vertices[vertexCount] = new VertexPositionColor(new Vector3(center, 0), color);
boundingBox = new Rectangle((int)minX, (int)minY, (int)(maxX-minX), (int)(maxY-minY));
primitiveCount = points.Length;
indices = new short[primitiveCount * 3];

View File

@@ -1,6 +1,7 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
using System.Diagnostics;
namespace Subsurface.Lights
{
@@ -56,15 +57,28 @@ namespace Subsurface.Lights
public void DrawLOS(GraphicsDevice graphics, Camera cam, Vector2 pos)
{
Stopwatch sw = new Stopwatch();
sw.Start();
Rectangle camView = new Rectangle(cam.WorldView.X, cam.WorldView.Y - cam.WorldView.Height, cam.WorldView.Width, cam.WorldView.Height);
if (!LosEnabled) return;
foreach (ConvexHull convexHull in ConvexHull.list)
{
if (!camView.Intersects(convexHull.BoundingBox)) continue;
convexHull.DrawShadows(graphics, cam, pos);
}
long elapsed = sw.ElapsedTicks;
Debug.WriteLine("los: "+elapsed);
}
public void DrawLightmap(GraphicsDevice graphics, SpriteBatch spriteBatch, Camera cam)
{
Stopwatch sw = new Stopwatch();
sw.Start();
graphics.SetRenderTarget(lightMap);
Rectangle viewRect = cam.WorldView;
@@ -88,6 +102,7 @@ namespace Subsurface.Lights
foreach (ConvexHull ch in ConvexHull.list)
{
if (!MathUtils.CircleIntersectsRectangle(light.Position, light.Range, ch.BoundingBox)) continue;
//draw shadow
ch.DrawShadows(graphics, cam, light.Position, false);
}
@@ -101,6 +116,10 @@ namespace Subsurface.Lights
//clear alpha, to avoid messing stuff up later
ClearAlphaToOne(graphics, spriteBatch);
graphics.SetRenderTarget(null);
long elapsed = sw.ElapsedTicks;
Debug.WriteLine("lights: " + elapsed);
}
private void ClearAlphaToOne(GraphicsDevice graphics, SpriteBatch spriteBatch)

View File

@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using RestSharp;
namespace Subsurface.Networking
{
@@ -18,6 +19,11 @@ namespace Subsurface.Networking
private TimeSpan SparseUpdateInterval = new TimeSpan(0, 0, 0, 1);
private DateTime sparseUpdateTimer;
private TimeSpan refreshMasterInterval = new TimeSpan(0, 0, 40);
private DateTime refreshMasterTimer;
private bool registeredToMaster;
private Client myClient;
public GameServer(string name, int port)
@@ -33,6 +39,7 @@ namespace Subsurface.Networking
//config.SimulatedMinimumLatency = 0.25f;
config.Port = port;
Port = port;
config.EnableUPnP = true;
@@ -44,7 +51,7 @@ namespace Subsurface.Networking
{
server = new NetServer(config);
server.Start();
// attempt to forward port
server.UPnP.ForwardPort(port, "subsurface");
@@ -55,12 +62,69 @@ namespace Subsurface.Networking
DebugConsole.ThrowError("Couldn't start the server", e);
}
RegisterToMasterServer();
updateInterval = new TimeSpan(0, 0, 0, 0, 30);
DebugConsole.NewMessage("Server started", Color.Green);
}
private void RegisterToMasterServer()
{
var client = new RestClient(NetworkMember.MasterServerUrl);
var request = new RestRequest("masterserver.php", Method.GET);
request.AddParameter("action", "addserver");
request.AddParameter("servername", name);
request.AddParameter("serverport", Port);
request.AddParameter("playercount", PlayerCountToByte(connectedClients.Count, config.MaximumConnections));
// execute the request
RestResponse response = (RestResponse)client.Execute(request);
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
DebugConsole.ThrowError("Error while connecting to master server (" +response.StatusCode+": "+response.StatusDescription+")");
return;
}
if (response!=null && !string.IsNullOrWhiteSpace(response.Content))
{
DebugConsole.ThrowError("Error while connecting to master server (" +response.Content+")");
return;
}
registeredToMaster = true;
refreshMasterTimer = DateTime.Now + refreshMasterInterval;
}
private void RefreshMaster()
{
var client = new RestClient(NetworkMember.MasterServerUrl);
var request = new RestRequest("masterserver.php", Method.GET);
request.AddParameter("action", "refreshserver");
request.AddParameter("gamestarted", gameStarted ? 1 : 0);
request.AddParameter("playercount", PlayerCountToByte(connectedClients.Count, config.MaximumConnections));
System.Diagnostics.Debug.WriteLine("refreshing master");
var sw = new Stopwatch();
sw.Start();
RestResponse response = (RestResponse)client.Execute(request);
sw.Stop();
System.Diagnostics.Debug.WriteLine("took "+sw.ElapsedMilliseconds+" ms");
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
DebugConsole.ThrowError("Error while connecting to master server (" +response.StatusCode+": "+response.StatusDescription+")");
}
}
public override void Update(float deltaTime)
{
base.Update(deltaTime);
@@ -92,6 +156,13 @@ namespace Subsurface.Networking
updateTimer = DateTime.Now + updateInterval;
}
if (registeredToMaster && refreshMasterTimer < DateTime.Now)
{
RefreshMaster();
refreshMasterTimer = DateTime.Now + refreshMasterInterval;
}
}
private void SparseUpdate()
@@ -724,6 +795,16 @@ namespace Subsurface.Networking
return preferredClient;
}
private byte PlayerCountToByte(int playerCount, int maxPlayers)
{
byte byteVal = (byte)playerCount;
byteVal |= (byte)((maxPlayers-1) << 4);
return byteVal;
}
/// <summary>
/// sends some random data to the clients
/// use for debugging purposes

View File

@@ -33,6 +33,8 @@ namespace Subsurface.Networking
{
public const int DefaultPort = 14242;
public static string MasterServerUrl = Game1.Config.MasterServerUrl;
protected static Color[] messageColor = { Color.White, Color.Red, Color.LightBlue, Color.LightGreen };
protected string name;
@@ -224,6 +226,15 @@ namespace Subsurface.Networking
public virtual void Disconnect() { }
public static int ByteToPlayerCount(byte byteVal, out int maxPlayers)
{
maxPlayers = (byteVal >> 4)+1;
int playerCount = byteVal & (byte)((1 << 4) - 1);
return playerCount;
}
}
enum ChatMessageType

View File

@@ -9,7 +9,7 @@ namespace Subsurface
{
class MainMenuScreen : Screen
{
public enum Tabs { Main = 0, NewGame = 1, LoadGame = 2, JoinServer = 3, HostServer = 4 }
public enum Tabs { Main = 0, NewGame = 1, LoadGame = 2, HostServer = 3 }
private GUIFrame[] menuTabs;
private GUIListBox mapList;
@@ -49,8 +49,8 @@ namespace Subsurface
//button.Enabled = false;
button = new GUIButton(new Rectangle(0, 120, 0, 30), "Join Server", Alignment.CenterX, GUI.style, menuTabs[(int)Tabs.Main]);
button.UserData = (int)Tabs.JoinServer;
button.OnClicked = SelectTab;
//button.UserData = (int)Tabs.JoinServer;
button.OnClicked = JoinServerClicked;
button = new GUIButton(new Rectangle(0, 180, 0, 30), "Host Server", Alignment.CenterX, GUI.style, menuTabs[(int)Tabs.Main]);
button.UserData = (int)Tabs.HostServer;
@@ -143,19 +143,22 @@ namespace Subsurface
//----------------------------------------------------------------------
menuTabs[(int)Tabs.JoinServer] = new GUIFrame(panelRect, GUI.style);
//menuTabs[(int)Tabs.JoinServer].Padding = GUI.style.smallPadding;
//menuTabs[(int)Tabs.JoinServer] = new GUIFrame(panelRect, GUI.style);
////menuTabs[(int)Tabs.JoinServer].Padding = GUI.style.smallPadding;
new GUITextBlock(new Rectangle(0, 0, 0, 30), "Join Server", GUI.style, Alignment.CenterX, Alignment.CenterX, menuTabs[(int)Tabs.JoinServer]);
//new GUITextBlock(new Rectangle(0, 0, 0, 30), "Join Server", GUI.style, Alignment.CenterX, Alignment.CenterX, menuTabs[(int)Tabs.JoinServer]);
new GUITextBlock(new Rectangle(0, 30, 0, 30), "Your Name:", GUI.style, Alignment.CenterX, Alignment.CenterX, menuTabs[(int)Tabs.JoinServer]);
clientNameBox = new GUITextBox(new Rectangle(0, 60, 200, 30), Color.White, Color.Black, Alignment.CenterX, Alignment.CenterX, null, menuTabs[(int)Tabs.JoinServer]);
//new GUITextBlock(new Rectangle(0, 30, 0, 30), "Your Name:", GUI.style, Alignment.CenterX, Alignment.CenterX, menuTabs[(int)Tabs.JoinServer]);
//clientNameBox = new GUITextBox(new Rectangle(0, 60, 200, 30), Color.White, Color.Black, Alignment.CenterX, Alignment.CenterX, null, menuTabs[(int)Tabs.JoinServer]);
new GUITextBlock(new Rectangle(0, 100, 0, 30), "Server IP:", GUI.style, Alignment.CenterX, Alignment.CenterX, menuTabs[(int)Tabs.JoinServer]);
ipBox = new GUITextBox(new Rectangle(0, 130, 200, 30), Color.White, Color.Black, Alignment.CenterX, Alignment.CenterX, null, menuTabs[(int)Tabs.JoinServer]);
GUIButton joinButton = new GUIButton(new Rectangle(0, 0, 200, 30), "Join", Alignment.BottomCenter, GUI.style, menuTabs[(int)Tabs.JoinServer]);
joinButton.OnClicked = JoinServer;
//new GUITextBlock(new Rectangle(0, 100, 0, 30), "Server IP:", GUI.style, Alignment.CenterX, Alignment.CenterX, menuTabs[(int)Tabs.JoinServer]);
//ipBox = new GUITextBox(new Rectangle(0, 130, 200, 30), Color.White, Color.Black, Alignment.CenterX, Alignment.CenterX, null, menuTabs[(int)Tabs.JoinServer]);
//GUIButton joinButton = new GUIButton(new Rectangle(0, 200, 200, 30), "Join", Alignment.CenterX, GUI.style, menuTabs[(int)Tabs.JoinServer]);
//joinButton.OnClicked = JoinServer;
//GUIButton serverListButton = new GUIButton(new Rectangle(0, 0, 230, 30), "Server List", Alignment.BottomCenter, GUI.style, menuTabs[(int)Tabs.JoinServer]);
//serverListButton.OnClicked = ServerListClicked;
//----------------------------------------------------------------------
@@ -176,7 +179,7 @@ namespace Subsurface
hostButton.OnClicked = HostServerClicked;
//----------------------------------------------------------------------
for (int i = 1; i < 5; i++ )
for (int i = 1; i < 4; i++ )
{
button = new GUIButton(new Rectangle(-20, -20, 100, 30), "Back", Alignment.TopLeft, GUI.style, menuTabs[i]);
button.OnClicked = PreviousTab;
@@ -196,16 +199,28 @@ namespace Subsurface
return true;
}
private bool JoinServerClicked(GUIButton button, object obj)
{
Game1.ServerListScreen.Select();
return true;
}
private bool HostServerClicked(GUIButton button, object obj)
{
string name = serverNameBox.Text;
if (string.IsNullOrEmpty(name)) name = "Server";
if (string.IsNullOrEmpty(name))
{
serverNameBox.Flash();
return false;
}
int port;
if (!int.TryParse(portBox.Text, out port))
if (!int.TryParse(portBox.Text, out port) || port < 0 || port > 65535)
{
DebugConsole.ThrowError("ERROR: " + portBox.Text + " is not a valid port. Using the default port " + NetworkMember.DefaultPort);
port = NetworkMember.DefaultPort;
portBox.Text = NetworkMember.DefaultPort.ToString();
portBox.Flash();
return false;
}
Game1.NetworkMember = new GameServer(name, port);

View File

@@ -145,7 +145,7 @@ namespace Subsurface
//submarine list ------------------------------------------------------------------
int columnWidth = infoFrame.Rect.Width / 3 - 30;
int columnWidth = infoFrame.Rect.Width / 5 - 30;
int columnX = 0;
new GUITextBlock(new Rectangle(columnX, 120, columnWidth, 30), "Selected submarine:", GUI.style, infoFrame);
@@ -177,7 +177,8 @@ namespace Subsurface
new GUITextBlock(new Rectangle(columnX, 120, 0, 30), "Selected game mode: ", GUI.style, infoFrame);
modeList = new GUIListBox(new Rectangle(columnX, 150, columnWidth, infoFrame.Rect.Height - 150 - 80), GUI.style, infoFrame);
foreach (GameModePreset mode in GameModePreset.list)
{
if (mode.IsSinglePlayer) continue;
@@ -191,7 +192,18 @@ namespace Subsurface
textBlock.UserData = mode;
}
columnX += columnWidth + 20;
columnX += columnWidth;
//gamemode description ------------------------------------------------------------------
var modeDescription = new GUITextBlock(
new Rectangle(columnX, 150, (int)(columnWidth * 1.5f), infoFrame.Rect.Height - 150 - 80),
"", Color.Black*0.3f, Color.White, Alignment.TopLeft, Alignment.TopLeft, GUI.style, infoFrame, true);
modeList.UserData = modeDescription;
columnX += modeDescription.Rect.Width + 40;
//duration ------------------------------------------------------------------
@@ -249,16 +261,18 @@ namespace Subsurface
serverMessage.Enabled = Game1.Server != null;
ServerName = (Game1.Server==null) ? "Server" : Game1.Server.Name;
modeList.OnSelected += SelectMode;
infoFrame.RemoveChild(infoFrame.children.Find(c => c.UserData as string == "startButton"));
if (IsServer && Game1.Server != null)
{
GUIButton startButton = new GUIButton(new Rectangle(0, 0, 200, 30), "Start", Alignment.TopRight, GUI.style, infoFrame);
GUIButton startButton = new GUIButton(new Rectangle(0, 0, 200, 30), "Start", Alignment.BottomRight, GUI.style, infoFrame);
startButton.OnClicked = Game1.Server.StartGame;
startButton.UserData = "startButton";
//mapList.OnSelected = new GUIListBox.OnSelectedHandler(Game1.server.UpdateNetLobby);
modeList.OnSelected = Game1.Server.UpdateNetLobby;
modeList.OnSelected += Game1.Server.UpdateNetLobby;
durationBar.OnMoved = Game1.Server.UpdateNetLobby;
if (subList.CountChildren > 0) subList.Select(0);
@@ -412,7 +426,6 @@ namespace Subsurface
GUI.Draw((float)deltaTime, spriteBatch, null);
spriteBatch.End();
}
public void NewChatMessage(string message, Color color)
@@ -478,6 +491,21 @@ namespace Subsurface
return true;
}
private bool SelectMode(object obj)
{
GameModePreset modePreset = obj as GameModePreset;
if (modePreset == null) return false;
GUITextBlock description = modeList.UserData as GUITextBlock;
description.Text = modePreset.Description;
//if (Game1.Server != null) Game1.Server.UpdateNetLobby(null);
return true;
}
private bool SelectSeed(GUITextBox textBox, string seed)
{
if (!string.IsNullOrWhiteSpace(seed))

View File

@@ -0,0 +1,216 @@
using System;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Subsurface.Networking;
using FarseerPhysics;
using FarseerPhysics.Factories;
using FarseerPhysics.Dynamics;
using System.IO;
using System.Collections.Generic;
using RestSharp;
namespace Subsurface
{
class ServerListScreen : Screen
{
private GUIFrame menu;
private GUIListBox serverList;
private GUIButton joinButton;
private GUITextBox clientNameBox, ipBox;
public ServerListScreen()
{
int width = Math.Min(Game1.GraphicsWidth - 160, 1000);
int height = Math.Min(Game1.GraphicsHeight - 160, 700);
Rectangle panelRect = new Rectangle(0, 0, width, height);
menu = new GUIFrame(panelRect, null, Alignment.Center, GUI.style);
new GUITextBlock(new Rectangle(0, 0, 0, 30), "Join Server", GUI.style, Alignment.CenterX, Alignment.CenterX, menu);
new GUITextBlock(new Rectangle(0, 30, 0, 30), "Your Name:", GUI.style, menu);
clientNameBox = new GUITextBox(new Rectangle(0, 60, 200, 30), GUI.style, menu);
new GUITextBlock(new Rectangle(0, 100, 0, 30), "Server IP:", GUI.style, menu);
ipBox = new GUITextBox(new Rectangle(0, 130, 200, 30), GUI.style, menu);
int middleX = (int)(width * 0.4f);
serverList = new GUIListBox(new Rectangle(middleX,60,0,(int)(height*0.7f)), GUI.style, menu);
serverList.OnSelected = SelectServer;
new GUITextBlock(new Rectangle(middleX, 30, 0, 30), "Name", GUI.style, menu);
new GUITextBlock(new Rectangle(middleX, 30, 0, 30), "Players", GUI.style, Alignment.TopLeft, Alignment.TopCenter, menu);
new GUITextBlock(new Rectangle(middleX, 30, 0, 30), "Game running", GUI.style, Alignment.TopLeft, Alignment.TopRight, menu);
joinButton = new GUIButton(new Rectangle(-170, 0, 150, 30), "Refresh", Alignment.BottomRight, GUI.style, menu);
joinButton.OnClicked = RefreshServers;
joinButton = new GUIButton(new Rectangle(0,0,150,30), "Join", Alignment.BottomRight, GUI.style, menu);
joinButton.OnClicked = JoinServer;
//joinButton.Enabled = false;
}
public override void Select()
{
base.Select();
UpdateServerList();
}
private bool SelectServer(object obj)
{
string ip = obj as string;
if (string.IsNullOrWhiteSpace(ip)) return false;
ipBox.Text = ip;
return true;
}
private bool RefreshServers(GUIButton button, object obj)
{
UpdateServerList();
return true;
}
private void UpdateServerList()
{
serverList.ClearChildren();
string masterServerData = GetMasterServerData();
if (string.IsNullOrWhiteSpace(masterServerData))
{
var nameText = new GUITextBlock(new Rectangle(0, 0, 0, 20), "Couldn't find any servers", GUI.style, serverList);
return;
}
if (masterServerData.Substring(0,5).ToLower()=="error")
{
DebugConsole.ThrowError("Error while connecting to master server ("+masterServerData+")!");
return;
}
string[] lines = masterServerData.Split('\n');
for (int i = 0; i<lines.Length; i++)
{
string[] arguments = lines[i].Split('|');
if (arguments.Length < 3) continue;
string IP = arguments[0];
string port = arguments[1];
string serverName = arguments[2];
string gameStarted = (arguments.Length > 3) ? arguments[3] : "";
string playerCountStr = (arguments.Length > 4) ? arguments[4] : "";
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 nameText = new GUITextBlock(new Rectangle(0,0,0,0), serverName, GUI.style, serverFrame);
int playerCount, maxPlayers;
playerCount = GameClient.ByteToPlayerCount((byte)int.Parse(playerCountStr), out maxPlayers);
var playerCountText = new GUITextBlock(new Rectangle(0, 0, 0, 0), playerCount+"/"+maxPlayers, GUI.style, Alignment.Left, Alignment.TopCenter, serverFrame);
var gameStartedText = new GUITextBlock(new Rectangle(0, 0, 0, 0), gameStarted=="1" ? "Yes" : "No", GUI.style, Alignment.Left, Alignment.TopRight, serverFrame);
}
}
private string GetMasterServerData()
{
RestClient client = null;
try
{
client = new RestClient(NetworkMember.MasterServerUrl);
}
catch (Exception e)
{
DebugConsole.ThrowError("Error while connecting to master server", e);
return "";
}
var request = new RestRequest("masterserver.php", Method.GET);
request.AddParameter("gamename", "subsurface"); // adds to POST or URL querystring based on Method
request.AddParameter("action", "listservers"); // adds to POST or URL querystring based on Method
// easily add HTTP Headers
//request.AddHeader("header", "value");
//// add files to upload (works with compatible verbs)
//request.AddFile(path);
// execute the request
RestResponse response = (RestResponse)client.Execute(request);
if (response.StatusCode!= System.Net.HttpStatusCode.OK)
{
DebugConsole.ThrowError("Error while connecting to master server (" +response.StatusCode+": "+response.StatusDescription+")");
return "";
}
return response.Content; // raw content as string
}
private bool JoinServer(GUIButton button, object obj)
{
if (string.IsNullOrWhiteSpace(clientNameBox.Text))
{
clientNameBox.Flash();
return false;
}
string ip = ipBox.Text;
if (string.IsNullOrWhiteSpace(ip))
{
ipBox.Flash();
return false;
}
Game1.NetworkMember = new GameClient(clientNameBox.Text);
Game1.Client.ConnectToServer(ip);
return true;
}
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
{
graphics.Clear(Color.CornflowerBlue);
Game1.GameScreen.DrawMap(graphics, spriteBatch);
spriteBatch.Begin();
menu.Draw(spriteBatch);
//if (previewPlayer!=null) previewPlayer.Draw(spriteBatch);
GUI.Draw((float)deltaTime, spriteBatch, null);
spriteBatch.End();
}
public override void Update(double deltaTime)
{
menu.Update((float)deltaTime);
GUI.Update((float)deltaTime);
}
}
}

View File

@@ -155,9 +155,7 @@ namespace Subsurface
public static bool CircleIntersectsRectangle(Vector2 circlePos, float radius, Rectangle rect)
{
Vector2 circleDistance = new Vector2(Math.Abs(circlePos.X - rect.Center.X), Math.Abs(circlePos.Y -rect.Center.Y));
if (circleDistance.X > (rect.Width / 2 + radius)) { return false; }
if (circleDistance.Y > (rect.Height / 2 + radius)) { return false; }

View File

@@ -38,7 +38,7 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>x64</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Windows\Release\</OutputPath>
@@ -78,6 +78,7 @@
<Compile Include="Source\Items\FixRequirement.cs" />
<Compile Include="Source\Map\Lights\Light.cs" />
<Compile Include="Source\Map\LocationType.cs" />
<Compile Include="Source\Screens\ServerListScreen.cs" />
<Compile Include="Source\Utils\Rand.cs" />
<Compile Include="Source\Events\PropertyTask.cs" />
<Compile Include="Source\Events\RepairTask.cs" />
@@ -228,6 +229,9 @@
<HintPath>.\OpenTK.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="RestSharp">
<HintPath>..\packages\RestSharp.105.1.0\lib\net4\RestSharp.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml" />
@@ -899,6 +903,7 @@
<None Include="Content\Sounds\Water\WaterAmbience.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Folder Include="Content\SavedMaps\" />

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="RestSharp" version="105.1.0" targetFramework="net40" />
</packages>

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>RestSharp</id>
<version>105.1.0</version>
<authors>John Sheehan, RestSharp Community</authors>
<owners>John Sheehan, RestSharp Community</owners>
<licenseUrl>https://github.com/restsharp/RestSharp/blob/master/LICENSE.txt</licenseUrl>
<projectUrl>http://restsharp.org/</projectUrl>
<iconUrl>http://dl.dropbox.com/u/1827/restsharp100.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Simple REST and HTTP API Client</description>
<releaseNotes>For full release notes see https://github.com/restsharp/RestSharp/blob/master/releasenotes.markdown</releaseNotes>
<language>en-US</language>
<tags>REST HTTP API JSON XML</tags>
</metadata>
</package>

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

22
packages/RestSharp.105.1.0/readme.txt vendored Normal file
View File

@@ -0,0 +1,22 @@
*** IMPORTANT CHANGE IN RESTSHARP VERSION 103 ***
In 103.0, JSON.NET was removed as a dependency.
If this is still installed in your project and no other libraries depend on
it you may remove it from your installed packages.
There is one breaking change: the default Json*Serializer* is no longer
compatible with Json.NET. To use Json.NET for serialization, copy the code
from https://github.com/restsharp/RestSharp/blob/86b31f9adf049d7fb821de8279154f41a17b36f7/RestSharp/Serializers/JsonSerializer.cs
and register it with your client:
var client = new RestClient();
client.JsonSerializer = new YourCustomSerializer();
The default Json*Deserializer* is mostly compatible, but it does not support
all features which Json.NET has (like the ability to support a custom [JsonConverter]
by decorating a certain property with an attribute). If you need these features, you
must take care of the deserialization yourself to get it working.
If you run into any compatibility issues with deserialization,
please report it to http://groups.google.com/group/restsharp

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<repositories>
<repository path="..\Subsurface\packages.config" />
</repositories>