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
+6 -6
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);
+24
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))
+3
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)
+10 -2
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();
}
+17 -3
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);
}
}
}
+9
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())
+18 -1
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];
@@ -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)
+82 -1
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
@@ -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
+33 -18
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);
+34 -6
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))
@@ -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);
}
}
}
+1 -3
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; }