Merge branch 'GuiManuel'

This commit is contained in:
2014-05-01 21:13:41 +02:00
24 changed files with 739 additions and 538 deletions

View File

@@ -1,11 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace inf3
{
class DummyBackend
{
}
}

View File

@@ -1,257 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Frontend;
using WorldOfPeacecraft;
using System.Threading;
namespace inf3
{
public class ParserTest
{
static void Main()
{
Parser p = new Parser();
p.AddToBuffer("begin:5");
//Console.WriteLine(p.getBuffer().Dequeue());
p.AddToBuffer("begin:upd");
p.AddToBuffer("begin:player");
p.AddToBuffer("id:3");
p.AddToBuffer("typ:Player");
p.AddToBuffer("busy:false");
p.AddToBuffer("desc:Player3");
p.AddToBuffer("x:3");
p.AddToBuffer("y:15");
p.AddToBuffer("points:0");
p.AddToBuffer("end:player");
p.AddToBuffer("end:upd");
p.AddToBuffer("end:5");
/*
p.AddToBuffer("begin:24");
p.AddToBuffer("begin:players");
p.AddToBuffer("begin:player");
p.AddToBuffer("id:3");
p.AddToBuffer("typ:Player");
p.AddToBuffer("busy:false");
p.AddToBuffer("desc:Player3");
p.AddToBuffer("x:3");
p.AddToBuffer("y:15");
p.AddToBuffer("pnts:0");
p.AddToBuffer("end:player");
p.AddToBuffer("begin:player");
p.AddToBuffer("id:6");
p.AddToBuffer("typ:Player");
p.AddToBuffer("busy:false");
p.AddToBuffer("desc:Player6");
p.AddToBuffer("x:17");
p.AddToBuffer("y:13");
p.AddToBuffer("pnts:0");
p.AddToBuffer("end:player");
p.AddToBuffer("end:players");
p.AddToBuffer("end:24");
*/
/*begin:14
begin:map
width:5
height:5
begin:cells
begin:cell
row:0
col:0
begin:props
WALL
end:props
end:cell
begin:cell
row:0
col:1
begin:props
WALL
end:props
end:cell
begin:cell
row:0
col:2
begin:props
WALL
end:props
end:cell
begin:cell
row:0
col:3
begin:props
WALL
end:props
end:cell
begin:cell
row:0
col:4
begin:props
WALL
end:props
end:cell
begin:cell
row:1
col:0
begin:props
WALL
end:props
end:cell
begin:cell
row:1
col:1
begin:props
WALKABLE
end:props
end:cell
begin:cell
row:1
col:2
begin:props
FOREST
WALKABLE
end:props
end:cell
begin:cell
row:1
col:3
begin:props
FOREST
WALKABLE
end:props
end:cell
begin:cell
row:1
col:4
begin:props
FOREST
WALKABLE
end:props
end:cell
begin:cell
row:2
col:0
begin:props
WALL
end:props
end:cell
begin:cell
row:2
col:1
begin:props
WALKABLE
end:props
end:cell
begin:cell
row:2
col:2
begin:props
FOREST
WALKABLE
end:props
end:cell
begin:cell
row:2
col:3
begin:props
FOREST
WALKABLE
end:props
end:cell
begin:cell
row:2
col:4
begin:props
FOREST
WALKABLE
end:props
end:cell
begin:cell
row:3
col:0
begin:props
WALL
end:props
end:cell
begin:cell
row:3
col:1
begin:props
WALKABLE
end:props
end:cell
begin:cell
row:3
col:2
begin:props
FOREST
WALKABLE
end:props
end:cell
begin:cell
row:3
col:3
begin:props
WALL
end:props
end:cell
begin:cell
row:3
col:4
begin:props
WALL
end:props
end:cell
begin:cell
row:4
col:0
begin:props
WALL
end:props
end:cell
begin:cell
row:4
col:1
begin:props
WALKABLE
end:props
end:cell
begin:cell
row:4
col:2
begin:props
FOREST
WALKABLE
end:props
end:cell
begin:cell
row:4
col:3
begin:props
FOREST
WALKABLE
end:props
end:cell
begin:cell
row:4
col:4
begin:props
FOREST
WALKABLE
end:props
end:cell
*/
Thread.Sleep(1000);
Console.WriteLine(p.getDummyPlayer().ToString());
Console.ReadLine();
}
}
}

View File

@@ -9,26 +9,27 @@
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RootNamespace>inf3</RootNamespace> <RootNamespace>inf3</RootNamespace>
<AssemblyName>inf3</AssemblyName> <AssemblyName>inf3</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>True</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>False</Optimize>
<OutputPath>bin\Debug</OutputPath> <OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants> <DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget> <PlatformTarget>x86</PlatformTarget>
<ConsolePause>false</ConsolePause> <ConsolePause>False</ConsolePause>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>none</DebugType> <DebugType>none</DebugType>
<Optimize>true</Optimize> <Optimize>True</Optimize>
<OutputPath>bin\Release</OutputPath> <OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget> <PlatformTarget>x86</PlatformTarget>
<ConsolePause>false</ConsolePause> <ConsolePause>False</ConsolePause>
</PropertyGroup> </PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup> <ItemGroup>
@@ -39,9 +40,6 @@
<Reference Include="System.Core" /> <Reference Include="System.Core" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="DummyBackend.cs" />
<Compile Include="ParserTest.cs" />
<Compile Include="src\Buffer.cs" />
<Compile Include="src\Receiver.cs" /> <Compile Include="src\Receiver.cs" />
<Compile Include="src\Sender.cs" /> <Compile Include="src\Sender.cs" />
<Compile Include="src\DefaultGui\DefaultGui.Designer.cs" /> <Compile Include="src\DefaultGui\DefaultGui.Designer.cs" />
@@ -69,10 +67,22 @@
<Compile Include="src\EnumDecision.cs" /> <Compile Include="src\EnumDecision.cs" />
<Compile Include="src\Online.cs" /> <Compile Include="src\Online.cs" />
<Compile Include="src\Time.cs" /> <Compile Include="src\Time.cs" />
<Compile Include="src\Buffer_Wafa.cs" />
<Compile Include="src\BufferManuel.cs" />
<Compile Include="src\Coordinate.cs" /> <Compile Include="src\Coordinate.cs" />
<Compile Include="src\Pathwalker.cs" /> <Compile Include="src\Pathwalker.cs" />
<Compile Include="src\Gui\Gui.cs" />
<Compile Include="src\Gui\IBackend.cs" />
<Compile Include="src\Gui\Program.cs" />
<Compile Include="src\Gui\ITile.cs" />
<Compile Include="src\Gui\IPositionable.cs" />
<Compile Include="src\Buffer.cs" />
<Compile Include="src\Gui\IGui.cs" />
<Compile Include="src\Gui\ChatPanel.cs" />
<Compile Include="src\Gui\ChatInputBox.cs" />
<Compile Include="src\Gui\ChatOutputBox.cs" />
<Compile Include="src\Gui\IChatMessage.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup />
<ItemGroup>
<Folder Include="src\Gui\" />
</ItemGroup>
</Project> </Project>

View File

@@ -2,33 +2,43 @@ using System.Net.Sockets;
using System.Collections.Generic; using System.Collections.Generic;
using WorldOfPeacecraft; using WorldOfPeacecraft;
namespace Frontend namespace WorldOfPeacecraft
{ {
public class Backend : IBackend public class Backend : IBackend
{ {
private Sender Send;
private Receiver Rec; private Receiver Rec;
private Parser Parse; private Parser Parse;
private TcpClient Client; private TcpClient Client;
private Dictionary<int, Dragon> Dragons; private Dictionary<int, Dragon> Dragons;
private Dictionary<int, Player> Players; private Dictionary<int, Player> Players;
private LinkedList<Message> ChatMessages;
private Map Map; private Map Map;
private Buffer Buffer; private Buffer SenderBuffer;
private IGui Gui;
public Backend () public Backend (IGui gui)
{ {
Parse = new Parser (Buffer); Gui = gui;
Client = new TcpClient ("localhost", 9999);
Rec = new Receiver (Client, Buffer);
Dragons = new Dictionary<int, Dragon> (); Dragons = new Dictionary<int, Dragon> ();
Players = new Dictionary<int, Player> (); Players = new Dictionary<int, Player> ();
ChatMessages = new LinkedList<Message> ();
Client = new TcpClient ("localhost", 9999);
Buffer receiverBuffer = new Buffer(10000);
SenderBuffer = new Buffer(100);
Parse = new Parser (this, receiverBuffer);
Rec = new Receiver (Client, receiverBuffer);
Send = new Sender (Client, SenderBuffer);
SenderBuffer.AddLine ("get:map");
SenderBuffer.AddLine ("get:ents");
} }
public IEnumerable<IPositionable> getDragons () public IEnumerable<IPositionable> GetDragons ()
{ {
return Dragons.Values; return Dragons.Values;
} }
public IEnumerable<IPositionable> getPlayers () public IEnumerable<IPositionable> GetPlayers ()
{ {
return Players.Values; return Players.Values;
} }
@@ -83,17 +93,50 @@ namespace Frontend
this.Map = map; this.Map = map;
} }
public ITile[,] getMap () public ITile[,] GetMap ()
{ {
if (Map == null) {
return null;
}
return Map.GetTiles (); return Map.GetTiles ();
} }
public void sendCommand (string command) public void AddChatMessage (Message message)
{ {
ChatMessages.AddLast (message);
} }
public void sendChat (string message) public IEnumerable<IChatMessage> GetChatMessages ()
{ {
return ChatMessages;
}
public void SendCommand (string command)
{
SenderBuffer.AddLine (command);
}
public void SendChatMessage (string message)
{
SenderBuffer.AddLine ("ask:say:" + message);
}
public void RefreshGui()
{
Gui.PerformRefresh();
}
public void StartThreads() {
Parse.Start ();
Rec.Start ();
Send.Start ();
}
public void Stop() {
Parse.Stop ();
Send.Stop ();
Rec.Stop ();
System.Windows.Forms.Application.Exit ();
} }
} }
} }

View File

@@ -1,35 +1,56 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading; using System.Threading;
namespace WorldOfPeacecraft namespace WorldOfPeacecraft
{ {
public class Buffer public class Buffer
{ {
private Queue<string> RawBuffer = new Queue<string>(); private Queue<string> Lines = new Queue<string>();
private AutoResetEvent BufferFilledEvent = new AutoResetEvent (false); private int MaxSize;
int size; private AutoResetEvent QueueFullLock = new AutoResetEvent(false);
private AutoResetEvent QueueEmptyLock = new AutoResetEvent(false);
public Buffer(int size) public Buffer (int maxSize)
{ {
this.size=size; this.MaxSize = maxSize;
} }
public void AddLine (string line)
public void AddToBuffer (string s)
{ {
if (RawBuffer.Count >= size){ bool waitRequired = false;
lock (Lines) {
if (Lines.Count >= MaxSize) {
waitRequired = true;
QueueFullLock.Reset ();
} }
else{ }
lock (RawBuffer) { if (waitRequired) {
RawBuffer.Enqueue (s); QueueFullLock.WaitOne ();
BufferFilledEvent.Set (); }
lock (Lines) {
Lines.Enqueue (line);
QueueEmptyLock.Set();
} }
} }
public string NextLine ()
{
bool waitRequired = false;
string line;
lock (Lines) {
if (Lines.Count == 0) {
waitRequired = true;
QueueEmptyLock.Reset ();
}
}
if (waitRequired) {
QueueEmptyLock.WaitOne ();
}
lock (Lines) {
line = Lines.Dequeue();
QueueFullLock.Set ();
}
return line;
} }
} }
} }

View File

@@ -1,56 +0,0 @@
using System.Collections.Generic;
using System.Threading;
namespace WorldOfPeacecraft
{
class BufferManuel
{
private Queue<string> Lines = new Queue<string>();
private int MaxSize;
private AutoResetEvent QueueFullLock = new AutoResetEvent(false);
private AutoResetEvent QueueEmptyLock = new AutoResetEvent(false);
public BufferManuel (int maxSize)
{
this.MaxSize = maxSize;
}
public void AddLine (string line)
{
bool waitRequired = false;
lock (Lines) {
if (Lines.Count >= MaxSize) {
waitRequired = true;
QueueFullLock.Reset ();
}
}
if (waitRequired) {
QueueFullLock.WaitOne ();
}
lock (Lines) {
Lines.Enqueue (line);
QueueEmptyLock.Set();
}
}
public string NextLine ()
{
bool waitRequired = false;
string line;
lock (Lines) {
if (Lines.Count == 0) {
waitRequired = true;
QueueEmptyLock.Reset ();
}
}
if (waitRequired) {
QueueEmptyLock.WaitOne ();
}
lock (Lines) {
line = Lines.Dequeue();
QueueFullLock.Set ();
}
return line;
}
}
}

View File

@@ -1,44 +0,0 @@
using System;
using System.Collections.Generic;
namespace WorldOfPeacecraft
{
public class Buffer_Wafa
{
private Queue<string> DotA2 = new Queue<string> ();
private int sizelimit;
public Buffer_Wafa (int limit)
{
sizelimit = limit;
}
bool isEmpty(){
if (DotA2.Count == 0)
return true;
else
return false;
}
bool isFull(){
if (DotA2.Count >= sizelimit)
return true;
else
return false;
}
string popMessage(){
//TODO
}
void enqueueMessage (string servermessage){
bool varIsFull = isFull();
if (varIsFull == false) {
DotA2.Enqueue (servermessage);
} else {
//this is else
}
}
}
}

View File

@@ -32,22 +32,22 @@ namespace WorldOfPeacecraft
return Id; return Id;
} }
public void SetPosX (int x) public void SetX (int x)
{ {
this.Coord.X = x; this.Coord.X = x;
} }
public int getXPosition () public int GetX ()
{ {
return Coord.X; return Coord.X;
} }
public void SetPosY (int y) public void SetY (int y)
{ {
this.Coord.Y = y; this.Coord.Y = y;
} }
public int getYPosition () public int GetY ()
{ {
return Coord.Y; return Coord.Y;
} }

82
src/Gui/ChatInputBox.cs Normal file
View File

@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace WorldOfPeacecraft
{
public class ChatInputBox : TextBox
{
private LinkedList<string> InputHistory = new LinkedList<string>();
private LinkedListNode<string> CurrentHistoryEntry;
public delegate void ChatMessageSubmittedEventHandler (string message);
public event ChatMessageSubmittedEventHandler ChatMessageSubmitted;
public ChatInputBox ()
{
this.KeyDown += KeyDownEvent;
this.KeyPress += KeyPressEvent;
}
private void KeyPressEvent (object o, KeyPressEventArgs args)
{
// Supress the "ding"-sound
if (args.KeyChar == (char)Keys.Return) {
args.Handled = true;
}
}
private void KeyDownEvent (object o, KeyEventArgs args)
{
if (args.KeyCode == Keys.Return) {
if (this.Text != "")
{
string message = this.Text;
this.Text = "";
if (CurrentHistoryEntry == null) {
InputHistory.AddLast (message);
}
else {
CurrentHistoryEntry.Value = message;
CurrentHistoryEntry = null;
}
if (ChatMessageSubmitted != null) {
this.ChatMessageSubmitted (message);
}
}
args.Handled = true;
} else if (args.KeyCode == Keys.Up) {
if (InputHistory.Count > 0) {
if (CurrentHistoryEntry == null) {
CurrentHistoryEntry = InputHistory.Last;
if (this.Text != "")
{
InputHistory.AddLast(this.Text);
}
this.Text = CurrentHistoryEntry.Value;
args.Handled = true;
} else {
if (CurrentHistoryEntry != InputHistory.First) {
CurrentHistoryEntry.Value = this.Text;
CurrentHistoryEntry = CurrentHistoryEntry.Previous;
this.Text = CurrentHistoryEntry.Value;
args.Handled = true;
}
}
}
} else if (args.KeyCode == Keys.Down) {
if (CurrentHistoryEntry != null)
{
CurrentHistoryEntry.Value = this.Text;
CurrentHistoryEntry = CurrentHistoryEntry.Next;
if (CurrentHistoryEntry == null) {
this.Text = "";
} else {
this.Text = CurrentHistoryEntry.Value;
}
}
}
}
}
}

52
src/Gui/ChatOutputBox.cs Normal file
View File

@@ -0,0 +1,52 @@
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace WorldOfPeacecraft
{
public class ChatOutputBox : RichTextBox
{
private IBackend Backend;
private Font MessageFont;
private Font SenderFont;
private Font IregularSenderFont;
public ChatOutputBox (IBackend backend)
{
Backend = backend;
this.ReadOnly = true;
this.Multiline = true;
MessageFont = this.SelectionFont;
SenderFont = new Font (MessageFont, FontStyle.Bold);
IregularSenderFont = new Font (MessageFont, FontStyle.Bold | FontStyle.Italic);
}
public void UpdateData ()
{
this.SuspendLayout ();
this.Clear ();
IEnumerable<IChatMessage> chatMessages = Backend.GetChatMessages ();
bool firstline = true;
lock (Backend) {
foreach (IChatMessage message in chatMessages) {
if (firstline) {
firstline = false;
} else {
this.AppendText ("\n");
}
if (message.IsSenderPlayer ()) {
this.SelectionFont = SenderFont;
} else {
this.SelectionFont = IregularSenderFont;
}
this.AppendText (message.GetSender ());
this.AppendText (": ");
this.SelectionFont = MessageFont;
this.AppendText (message.GetMessage ());
}
}
this.ResumeLayout ();
}
}
}

49
src/Gui/ChatPanel.cs Normal file
View File

@@ -0,0 +1,49 @@
using System.Drawing;
using System.Windows.Forms;
namespace WorldOfPeacecraft
{
public class ChatPanel : Panel
{
private ChatInputBox ChatInput;
private ChatOutputBox ChatOutput;
private IBackend Backend;
public ChatPanel (IBackend backend)
{
Backend = backend;
ChatInput = new ChatInputBox ();
ChatInput.ChatMessageSubmitted += OnChatMessageSent;
ChatOutput = new ChatOutputBox (backend);
this.Controls.Add (ChatInput);
this.Controls.Add (ChatOutput);
}
protected override void OnLayout (LayoutEventArgs levent)
{
int outputHeight = this.ClientSize.Height - ChatInput.Height;
ChatOutput.Location = new Point (0, 0);
ChatOutput.Size = new Size (this.ClientSize.Width, outputHeight);
ChatInput.Location = new Point (0, outputHeight);
ChatInput.Size = new Size (this.ClientSize.Width, ChatInput.ClientSize.Width);
base.OnLayout (levent);
}
private void OnChatMessageSent (string message)
{
if (message.StartsWith ("/")) {
string command = message.Substring (1);
Backend.SendCommand(command);
} else {
Backend.SendChatMessage(message);
}
// TODO Move focus to board?
}
public void UpdateData()
{
ChatOutput.UpdateData ();
}
}
}

158
src/Gui/Gui.cs Normal file
View File

@@ -0,0 +1,158 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WorldOfPeacecraft
{
class Gui : Form, IGui
{
private const int TileSize = 32;
private const int EntitySize = 10;
private const int ChatWidth = 300;
private IBackend Backend;
private Panel Board = new Panel();
private ChatPanel ChatPanel;
public Gui ()
{
AllocConsole();
}
public void SetBackend (IBackend backend)
{
Backend = backend;
}
protected override void OnLoad (EventArgs e)
{
base.OnLoad (e);
InitializeComponents ();
Backend.StartThreads ();
}
public void InitializeComponents ()
{
ChatPanel = new ChatPanel (Backend);
this.SuspendLayout();
this.Size = new Size(400 + ChatWidth, 400);
Board.Location = new Point(0,0);
Board.Size = new Size(400, 400);
Board.Paint += DoPaint;
ChatPanel.Location = new Point (400, 0);
ChatPanel.Size = new Size (300, 400);
this.DoubleBuffered = true;
this.MaximizeBox = false;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Name = "WorldOfPeacecraft";
this.ShowIcon = false;
this.Controls.Add (Board);
this.Controls.Add (ChatPanel);
this.ResumeLayout();
}
protected override void OnClosing (System.ComponentModel.CancelEventArgs e)
{
base.OnClosing (e);
Backend.Stop ();
}
public void DoPaint (object source, PaintEventArgs args)
{
BufferedGraphics buffer = BufferedGraphicsManager.Current.Allocate (Board.CreateGraphics (), Board.DisplayRectangle);
Graphics g = buffer.Graphics;
lock (Backend) {
PaintMap (g);
PaintEntities (g);
}
buffer.Render();
}
public void PaintMap (Graphics g)
{
ITile[,] Map = Backend.GetMap ();
if (Map != null) {
for (int y = 0; y < Map.GetLength(1); y++) {
for (int x = 0; x < Map.GetLength(0); x++) {
PaintTile (g, Map [x, y], x, y);
}
}
}
else {
g.FillRectangle(new SolidBrush(Color.White), Board.DisplayRectangle);
}
}
public void PaintTile (Graphics g, ITile tile, int x, int y)
{
int posx = x * TileSize;
int posy = y * TileSize;
Color color;
if (tile.IsForest ()) {
color = Color.Green;
} // Stupid parenthesis
else if (tile.IsHuntable ()) {
color = Color.BurlyWood;
} else if (tile.IsWalkable ()) {
color = Color.Yellow;
} else if (tile.IsWall ()) {
color = Color.DarkGray;
} else if (tile.IsWater ()) {
color = Color.Blue;
} else {
color = Color.Black;
}
g.FillRectangle(new SolidBrush(color), posx, posy, TileSize, TileSize);
}
public void PaintEntities (Graphics g)
{
IEnumerable<IPositionable> dragons = Backend.GetDragons ();
IEnumerable<IPositionable> players = Backend.GetPlayers ();
foreach (IPositionable dragon in dragons) {
PaintEntity (g, dragon);
}
foreach (IPositionable player in players) {
PaintEntity (g, player);
}
}
public void PaintEntity (Graphics g, IPositionable entity)
{
int x = entity.GetX () * TileSize + TileSize / 2 - EntitySize / 2;
int y = entity.GetY () * TileSize + TileSize / 2 - EntitySize / 2;
g.FillRectangle (new SolidBrush (Color.Red), x, y, EntitySize, EntitySize);
g.DrawRectangle (new Pen( new SolidBrush (Color.Black)), x, y, EntitySize, EntitySize);
}
public void PerformRefresh ()
{
this.BeginInvoke(new MethodInvoker(delegate
{
ITile[,] map = Backend.GetMap();
if (map == null) {
return;
}
int mapWidth = (map.GetLength(0)) * TileSize;
int mapHeight = (map.GetLength(1)) * TileSize;
this.SuspendLayout();
this.SetClientSizeCore(mapWidth + ChatWidth, mapHeight);
Board.Size = new Size(mapWidth, mapHeight);
ChatPanel.Location = new Point (mapWidth, 0);
ChatPanel.Size = new Size (ChatWidth, mapHeight);
this.ResumeLayout();
this.PerformLayout();
ChatPanel.UpdateData ();
this.Refresh();
}));
}
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool AllocConsole();
}
}

23
src/Gui/IBackend.cs Normal file
View File

@@ -0,0 +1,23 @@
using System.Collections.Generic;
namespace WorldOfPeacecraft
{
public interface IBackend
{
ITile[,] GetMap();
IEnumerable<IPositionable> GetPlayers();
IEnumerable<IPositionable> GetDragons();
IEnumerable<IChatMessage> GetChatMessages();
void SendChatMessage (string message);
void SendCommand (string command);
void StartThreads();
void Stop();
}
}

11
src/Gui/IChatMessage.cs Normal file
View File

@@ -0,0 +1,11 @@
namespace WorldOfPeacecraft
{
public interface IChatMessage
{
string GetMessage();
string GetSender();
bool IsSenderPlayer();
}
}

8
src/Gui/IGui.cs Normal file
View File

@@ -0,0 +1,8 @@
namespace WorldOfPeacecraft
{
public interface IGui
{
void PerformRefresh();
void SetBackend(IBackend backend);
}
}

26
src/Gui/IPositionable.cs Normal file
View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WorldOfPeacecraft
{
/// <summary>
/// Interface your positionable objects should implement. Such as the dragons and players.
/// This enables the frontend to determine the current position of said objects to render them at the correct space.
/// </summary>
public interface IPositionable
{
/// <summary>
/// Getter for the x-position
/// </summary>
/// <returns>the x-position</returns>
int GetX();
/// <summary>
/// Getter for the y-position
/// </summary>
/// <returns>the y-position</returns>
int GetY();
}
}

17
src/Gui/ITile.cs Normal file
View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WorldOfPeacecraft
{
public interface ITile : IPositionable
{
bool IsWalkable();
bool IsWall();
bool IsForest();
bool IsHuntable();
bool IsWater();
}
}

20
src/Gui/Program.cs Normal file
View File

@@ -0,0 +1,20 @@
using System;
using System.Windows.Forms;
namespace WorldOfPeacecraft
{
public class Program
{
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Gui gui = new Gui();
Backend backend = new Backend(gui);
gui.SetBackend(backend);
Application.Run (gui);
}
}
}

View File

@@ -13,8 +13,8 @@ namespace WorldOfPeacecraft
public void SetTile (Tile t) public void SetTile (Tile t)
{ {
int x = t.getX (); int x = t.GetX ();
int y = t.getY (); int y = t.GetY ();
map [x, y] = t; map [x, y] = t;
} }

View File

@@ -2,7 +2,7 @@
namespace WorldOfPeacecraft namespace WorldOfPeacecraft
{ {
public class Message public class Message : IChatMessage
{ {
int sourceID; int sourceID;
string source; string source;
@@ -14,6 +14,21 @@ namespace WorldOfPeacecraft
source = src; source = src;
text = txt; text = txt;
} }
public string GetMessage()
{
return text;
}
public string GetSender()
{
return source;
}
public bool IsSenderPlayer ()
{
return true;
}
} }
} }

View File

@@ -49,46 +49,29 @@ namespace WorldOfPeacecraft
public const string MessPlayers = "players"; public const string MessPlayers = "players";
public const string MessDragon = "dragon"; public const string MessDragon = "dragon";
public const string MessMapcell = "cell"; public const string MessMapcell = "cell";
private Buffer MonsterBuffer; private Buffer InputBuffer;
private Thread ParserThread; private Thread ParserThread;
private LinkedList<string> Message; private LinkedList<string> Message;
private Regex LastLineRegex; private Regex LastLineRegex;
private Backend backend; private Backend Backend;
public Parser (Buffer b) public Parser (Backend backend, Buffer buffer)
{ {
MonsterBuffer = b; InputBuffer = buffer;
ParserThread = new Thread (new ThreadStart (this.RunParser)); Backend = backend;
ParserThread.Start();
Message = new LinkedList<string> (); Message = new LinkedList<string> ();
LastLineRegex = new Regex ("^end:[0-9]+$"); LastLineRegex = new Regex ("^end:[0-9]+$");
ParserThread = new Thread (new ThreadStart (this.RunParser));
} }
private void RunParser () private void RunParser ()
{/* {
while (true) { while (true) {
bool waitRequired = false; Message.AddLast (InputBuffer.NextLine ());
lock (MonsterBuffer) {
if (MonsterBuffer.Count == 0) {
waitRequired = true;
BufferFilledEvent.Reset ();
}
}
if (waitRequired) {
BufferFilledEvent.WaitOne ();
}
lock (Buffer) {
Message.AddLast (Buffer.Dequeue ());
}
if (IsCompletePackage ()) { if (IsCompletePackage ()) {
Parse (); Parse ();
} }
}*/
} }
public Player getDummyPlayer()
{
return DummyPlayer;
} }
private void Parse () private void Parse ()
@@ -188,11 +171,17 @@ namespace WorldOfPeacecraft
switch (block.GetName ()) { switch (block.GetName ()) {
case MessPlayer: case MessPlayer:
Player player = MapPlayer (block); Player player = MapPlayer (block);
backend.removePlayer (player); lock (Backend) {
Backend.removePlayer (player);
}
Backend.RefreshGui ();
break; break;
case MessDragon: case MessDragon:
Dragon dragon = MapDragon (block); Dragon dragon = MapDragon (block);
backend.removeDragon (dragon); lock (Backend) {
Backend.removeDragon (dragon);
}
Backend.RefreshGui ();
break; break;
default: default:
ThrowUnknownBlockException(deleteBlock, block); ThrowUnknownBlockException(deleteBlock, block);
@@ -215,15 +204,22 @@ namespace WorldOfPeacecraft
foreach (Block cell in cellsBlock.GetBlocks()) { foreach (Block cell in cellsBlock.GetBlocks()) {
map.SetTile(MapMapcell(cell)); map.SetTile(MapMapcell(cell));
} }
backend.SetMap(map); lock (Backend) {
Backend.SetMap (map);
}
Backend.RefreshGui();
} }
private void ProcessMessage (Block mesBlock) private void ProcessMessage (Block mesBlock)
{ {
// TODO Ausnahmebehandlung von mehrzeiligen Nachrichten?
int srcid = mesBlock.GetIntValue (ValueSourceId); int srcid = mesBlock.GetIntValue (ValueSourceId);
string src = mesBlock.GetStringValue (ValueSource); string src = mesBlock.GetStringValue (ValueSource);
string txt = mesBlock.GetStringValue (ValueText); string txt = mesBlock.GetStringValue (ValueText);
Message m = new Message (srcid, src, txt); lock (Backend) {
Backend.AddChatMessage (new Message (srcid, src, txt));
}
Backend.RefreshGui ();
} }
private void ProcessAnswer (Block block) private void ProcessAnswer (Block block)
@@ -286,7 +282,6 @@ namespace WorldOfPeacecraft
break; break;
default: default:
throw new ParsingException("Invalid type"); // TODO Better message throw new ParsingException("Invalid type"); // TODO Better message
break;
} }
bool accepted = challengeBlock.GetBoolValue("accepted"); bool accepted = challengeBlock.GetBoolValue("accepted");
Challenge c = new Challenge(id, type, accepted); Challenge c = new Challenge(id, type, accepted);
@@ -295,12 +290,19 @@ namespace WorldOfPeacecraft
private void ProcessPlayer (Block playerBlock) private void ProcessPlayer (Block playerBlock)
{ {
backend.SetPlayer(MapPlayer(playerBlock)); lock (Backend) {
Backend.SetPlayer (MapPlayer (playerBlock));
}
Backend.RefreshGui ();
} }
private void ProcessMapcell (Block mapcellBlock) private void ProcessMapcell (Block mapcellBlock)
{ {
backend.getMapObject().SetTile(MapMapcell(mapcellBlock)); Tile tile = MapMapcell (mapcellBlock);
lock (Backend) {
Backend.getMapObject ().SetTile (tile);
}
Backend.RefreshGui ();
} }
private void ProcessYourid (Block yourIdBlock) private void ProcessYourid (Block yourIdBlock)
@@ -329,15 +331,19 @@ namespace WorldOfPeacecraft
private void ProcessEntities (Block entitiesBlock) private void ProcessEntities (Block entitiesBlock)
{ {
backend.clearDragons (); // This lock can be placed more efficiently. Does it make sense?
backend.clearPlayers (); lock (Backend) {
Backend.clearDragons ();
Backend.clearPlayers ();
foreach (Block entityBlock in entitiesBlock.GetBlocks ()) { foreach (Block entityBlock in entitiesBlock.GetBlocks ()) {
switch (entityBlock.GetName ()) { switch (entityBlock.GetName ()) {
case MessPlayer: case MessPlayer:
backend.SetPlayer(MapPlayer(entityBlock)); lock (Backend) {
Backend.SetPlayer (MapPlayer (entityBlock));
}
break; break;
case MessDragon: case MessDragon:
backend.SetDragon(MapDragon(entityBlock)); Backend.SetDragon (MapDragon (entityBlock));
break; break;
default: default:
ThrowUnknownBlockException (entitiesBlock, entityBlock); ThrowUnknownBlockException (entitiesBlock, entityBlock);
@@ -345,18 +351,28 @@ namespace WorldOfPeacecraft
} }
} }
} }
Backend.RefreshGui();
}
private void ProcessPlayers (Block playersBlock) private void ProcessPlayers (Block playersBlock)
{ {
backend.clearPlayers (); // This lock can be placed more efficiently. Does it make sense?
lock (Backend) {
Backend.clearPlayers ();
foreach (Block playerBlock in playersBlock.GetBlocks ()) { foreach (Block playerBlock in playersBlock.GetBlocks ()) {
backend.SetPlayer(MapPlayer(playerBlock)); Backend.SetPlayer (MapPlayer (playerBlock));
} }
} }
Backend.RefreshGui ();
}
private void ProcessDragon (Block dragonBlock) private void ProcessDragon (Block dragonBlock)
{ {
backend.SetDragon(MapDragon(dragonBlock)); Dragon dragon = MapDragon (dragonBlock);
lock (Backend) {
Backend.SetDragon (dragon);
}
Backend.RefreshGui ();
} }
private Dragon MapDragon (Block dragonBlock) private Dragon MapDragon (Block dragonBlock)
@@ -440,13 +456,16 @@ namespace WorldOfPeacecraft
return LastLineRegex.IsMatch (lastLine); return LastLineRegex.IsMatch (lastLine);
} }
public void Start ()
{
ParserThread.Start();
}
public void Stop () public void Stop ()
{ {
ParserThread.Abort (); ParserThread.Abort ();
} }
private class Block private class Block
{ {
private string Name; private string Name;

View File

@@ -9,15 +9,14 @@ namespace WorldOfPeacecraft
{ {
private TcpClient Client; private TcpClient Client;
private StreamReader Reader; private StreamReader Reader;
private Buffer KillerBuffer; private Buffer ReceiverBuffer;
private Thread ReceiverThread; private Thread ReceiverThread;
public Receiver (TcpClient client, Buffer buffer) public Receiver (TcpClient client, Buffer buffer)
{ {
this.Client = client; this.Client = client;
this.KillerBuffer = buffer; this.ReceiverBuffer = buffer;
ReceiverThread = new Thread(new ThreadStart(this.doReceive)); ReceiverThread = new Thread(new ThreadStart(this.doReceive));
ReceiverThread.Start();
} }
public string Receive () public string Receive ()
@@ -29,10 +28,15 @@ namespace WorldOfPeacecraft
{ {
this.Reader = new StreamReader (Client.GetStream ()); this.Reader = new StreamReader (Client.GetStream ());
while (true) { while (true) {
KillerBuffer.AddToBuffer(Receive()); ReceiverBuffer.AddLine(Receive());
} }
} }
public void Start()
{
ReceiverThread.Start ();
}
public void Stop() public void Stop()
{ {
ReceiverThread.Abort (); ReceiverThread.Abort ();

View File

@@ -2,16 +2,21 @@ using System;
using System.IO; using System.IO;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
using System.Threading;
namespace WorldOfPeacecraft namespace WorldOfPeacecraft
{ {
public class Sender public class Sender
{ {
private TcpClient Client; private TcpClient Client;
private Buffer Buffer;
private Thread SenderThread;
public Sender (TcpClient client) public Sender (TcpClient client, Buffer buffer)
{ {
this.Client = client; this.Client = client;
this.Buffer = buffer;
this.SenderThread = new Thread(new ThreadStart(this.threadStart));
} }
public void Send (String message) public void Send (String message)
@@ -20,5 +25,22 @@ namespace WorldOfPeacecraft
writer.WriteLine (message); writer.WriteLine (message);
writer.Flush (); writer.Flush ();
} }
private void threadStart ()
{
while (true) {
Send (Buffer.NextLine());
}
}
public void Start()
{
SenderThread.Start();
}
public void Stop()
{
SenderThread.Abort();
}
} }
} }

View File

@@ -5,115 +5,104 @@ namespace WorldOfPeacecraft
{ {
public class Tile : ITile public class Tile : ITile
{ {
public int x; public int X;
public int y; public int Y;
public Entity entity; public Entity Entity;
public bool walkable; public bool Walkable;
public bool wall; public bool Wall;
public bool forest; public bool Forest;
public bool huntable; public bool Huntable;
public bool water; public bool Water;
public Tile (int posX, int posY, bool walkable, bool wall, bool forest, bool huntable, bool water) public Tile (int posX, int posY, bool walkable, bool wall, bool forest, bool huntable, bool water)
{ {
this.setX (posX); this.SetX (posX);
this.setY (posY); this.SetY (posY);
this.setWalkable (walkable); this.SetWalkable (walkable);
this.setWall(wall); this.SetWall(wall);
this.setForest (forest); this.SetForest (forest);
this.setHuntable (huntable); this.SetHuntable (huntable);
this.setWater (water); this.SetWater (water);
} }
public void setX (int x) public void SetX (int x)
{ {
this.x = x; this.X = x;
} }
public int getX () public int GetX ()
{ {
return x; return X;
} }
public int getXPosition () public void SetY (int y)
{ {
return x; this.Y = y;
} }
public void setY (int y) public int GetY ()
{ {
this.y = y; return Y;
} }
public int getY () public void SetEntity (Entity entity)
{ {
return y; this.Entity = entity;
} }
public int getYPosition () public Entity GetEntity ()
{ {
return y; return Entity;
} }
public void setEntity (Entity entity) public void SetWalkable (bool walkable)
{ {
this.entity = entity; this.Walkable = walkable;
} }
public Entity getEntity () public bool IsWalkable ()
{ {
return entity; return Walkable;
} }
public void setWalkable (bool walkable) public void SetWall(bool wall)
{ {
this.walkable = walkable; this.Wall = wall;
} }
public bool isWalkable () public bool IsWall()
{ {
return walkable; return Wall;
} }
public void setWall(bool wall) public void SetForest (bool forest)
{ {
this.wall = wall; this.Forest = forest;
} }
public bool isWall() public bool IsForest ()
{ {
return wall; return Forest;
} }
public void SetHuntable (bool huntable)
public void setForest (bool forest)
{ {
this.forest = forest; this.Huntable = huntable;
} }
public bool isForest () public bool IsHuntable ()
{ {
return forest; return Huntable;
} }
public void setHuntable (bool huntable) public void SetWater (bool water)
{ {
this.huntable = huntable; this.Water = water;
} }
public bool isHuntable () public bool IsWater ()
{ {
return huntable; return Water;
}
public void setWater (bool water)
{
this.water = water;
}
public bool isWater ()
{
return water;
} }
} }
} }