diff --git a/DummyBackend.cs b/DummyBackend.cs deleted file mode 100644 index f4dfa1c..0000000 --- a/DummyBackend.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace inf3 -{ - class DummyBackend - { - } -} diff --git a/ParserTest.cs b/ParserTest.cs deleted file mode 100644 index 08c08ad..0000000 --- a/ParserTest.cs +++ /dev/null @@ -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(); - - } - } -} diff --git a/inf3.csproj b/inf3.csproj index 6f41c4a..eb5c186 100644 --- a/inf3.csproj +++ b/inf3.csproj @@ -9,26 +9,27 @@ Exe inf3 inf3 + v4.0 - true + True full - false + False bin\Debug DEBUG; prompt 4 x86 - false + False none - true + True bin\Release prompt 4 x86 - false + False @@ -39,9 +40,6 @@ - - - @@ -69,10 +67,22 @@ - - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Backend.cs b/src/Backend.cs index a098793..433e674 100644 --- a/src/Backend.cs +++ b/src/Backend.cs @@ -2,33 +2,43 @@ using System.Net.Sockets; using System.Collections.Generic; using WorldOfPeacecraft; -namespace Frontend +namespace WorldOfPeacecraft { public class Backend : IBackend { + private Sender Send; private Receiver Rec; private Parser Parse; private TcpClient Client; private Dictionary Dragons; private Dictionary Players; + private LinkedList ChatMessages; private Map Map; - private Buffer Buffer; + private Buffer SenderBuffer; + private IGui Gui; - public Backend () + public Backend (IGui gui) { - Parse = new Parser (Buffer); - Client = new TcpClient ("localhost", 9999); - Rec = new Receiver (Client, Buffer); + Gui = gui; Dragons = new Dictionary (); Players = new Dictionary (); + ChatMessages = new LinkedList (); + 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 getDragons () + public IEnumerable GetDragons () { return Dragons.Values; } - public IEnumerable getPlayers () + public IEnumerable GetPlayers () { return Players.Values; } @@ -83,17 +93,50 @@ namespace Frontend this.Map = map; } - public ITile[,] getMap () + public ITile[,] GetMap () { + if (Map == null) { + return null; + } return Map.GetTiles (); } - public void sendCommand (string command) + public void AddChatMessage (Message message) { + ChatMessages.AddLast (message); } - public void sendChat (string message) + public IEnumerable 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 (); } } } diff --git a/src/Buffer.cs b/src/Buffer.cs index a10d9a7..6bf6612 100644 --- a/src/Buffer.cs +++ b/src/Buffer.cs @@ -1,35 +1,56 @@ -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading; namespace WorldOfPeacecraft { - public class Buffer - { - private Queue RawBuffer = new Queue(); - private AutoResetEvent BufferFilledEvent = new AutoResetEvent (false); - int size; + public class Buffer + { + private Queue Lines = new Queue(); + private int MaxSize; + private AutoResetEvent QueueFullLock = new AutoResetEvent(false); + private AutoResetEvent QueueEmptyLock = new AutoResetEvent(false); - public Buffer(int size) - { - this.size=size; - } - - - public void AddToBuffer (string s) + public Buffer (int maxSize) { - if (RawBuffer.Count >= size){ + this.MaxSize = maxSize; + } - } - else{ - lock (RawBuffer) { - RawBuffer.Enqueue (s); - BufferFilledEvent.Set (); - } - } - - } - } + 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; + } + } } diff --git a/src/BufferManuel.cs b/src/BufferManuel.cs deleted file mode 100644 index 45d33f3..0000000 --- a/src/BufferManuel.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Collections.Generic; -using System.Threading; - -namespace WorldOfPeacecraft -{ - class BufferManuel - { - private Queue Lines = new Queue(); - 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; - } - } -} diff --git a/src/Buffer_Wafa.cs b/src/Buffer_Wafa.cs deleted file mode 100644 index 3ee9b43..0000000 --- a/src/Buffer_Wafa.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace WorldOfPeacecraft -{ - public class Buffer_Wafa - { - private Queue DotA2 = new Queue (); - 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 - } - } - } -} - diff --git a/src/Entity.cs b/src/Entity.cs index d81589e..a3a6187 100644 --- a/src/Entity.cs +++ b/src/Entity.cs @@ -32,22 +32,22 @@ namespace WorldOfPeacecraft return Id; } - public void SetPosX (int x) + public void SetX (int x) { this.Coord.X = x; } - public int getXPosition () + public int GetX () { return Coord.X; } - public void SetPosY (int y) + public void SetY (int y) { this.Coord.Y = y; } - public int getYPosition () + public int GetY () { return Coord.Y; } diff --git a/src/Gui/ChatInputBox.cs b/src/Gui/ChatInputBox.cs new file mode 100644 index 0000000..2ff32f8 --- /dev/null +++ b/src/Gui/ChatInputBox.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace WorldOfPeacecraft +{ + public class ChatInputBox : TextBox + { + private LinkedList InputHistory = new LinkedList(); + private LinkedListNode 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; + } + } + } + } + } + +} diff --git a/src/Gui/ChatOutputBox.cs b/src/Gui/ChatOutputBox.cs new file mode 100644 index 0000000..be05f88 --- /dev/null +++ b/src/Gui/ChatOutputBox.cs @@ -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 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 (); + } + } +} + diff --git a/src/Gui/ChatPanel.cs b/src/Gui/ChatPanel.cs new file mode 100644 index 0000000..bcc3e4e --- /dev/null +++ b/src/Gui/ChatPanel.cs @@ -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 (); + } + } +} diff --git a/src/Gui/Gui.cs b/src/Gui/Gui.cs new file mode 100644 index 0000000..f8786da --- /dev/null +++ b/src/Gui/Gui.cs @@ -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 dragons = Backend.GetDragons (); + IEnumerable 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(); + } +} diff --git a/src/Gui/IBackend.cs b/src/Gui/IBackend.cs new file mode 100644 index 0000000..7361313 --- /dev/null +++ b/src/Gui/IBackend.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; + +namespace WorldOfPeacecraft +{ + public interface IBackend + { + ITile[,] GetMap(); + + IEnumerable GetPlayers(); + + IEnumerable GetDragons(); + + IEnumerable GetChatMessages(); + + void SendChatMessage (string message); + + void SendCommand (string command); + + void StartThreads(); + + void Stop(); + } +} diff --git a/src/Gui/IChatMessage.cs b/src/Gui/IChatMessage.cs new file mode 100644 index 0000000..69b40ba --- /dev/null +++ b/src/Gui/IChatMessage.cs @@ -0,0 +1,11 @@ +namespace WorldOfPeacecraft +{ + public interface IChatMessage + { + string GetMessage(); + + string GetSender(); + + bool IsSenderPlayer(); + } +} \ No newline at end of file diff --git a/src/Gui/IGui.cs b/src/Gui/IGui.cs new file mode 100644 index 0000000..4a0a446 --- /dev/null +++ b/src/Gui/IGui.cs @@ -0,0 +1,8 @@ +namespace WorldOfPeacecraft +{ + public interface IGui + { + void PerformRefresh(); + void SetBackend(IBackend backend); + } +} diff --git a/src/Gui/IPositionable.cs b/src/Gui/IPositionable.cs new file mode 100644 index 0000000..4f586a4 --- /dev/null +++ b/src/Gui/IPositionable.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WorldOfPeacecraft +{ + /// + /// 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. + /// + public interface IPositionable + { + /// + /// Getter for the x-position + /// + /// the x-position + int GetX(); + /// + /// Getter for the y-position + /// + /// the y-position + int GetY(); + } +} diff --git a/src/Gui/ITile.cs b/src/Gui/ITile.cs new file mode 100644 index 0000000..cd61a15 --- /dev/null +++ b/src/Gui/ITile.cs @@ -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(); + } +} diff --git a/src/Gui/Program.cs b/src/Gui/Program.cs new file mode 100644 index 0000000..014673c --- /dev/null +++ b/src/Gui/Program.cs @@ -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); + } + } +} + diff --git a/src/Map.cs b/src/Map.cs index 65f368e..f61bf76 100644 --- a/src/Map.cs +++ b/src/Map.cs @@ -13,8 +13,8 @@ namespace WorldOfPeacecraft public void SetTile (Tile t) { - int x = t.getX (); - int y = t.getY (); + int x = t.GetX (); + int y = t.GetY (); map [x, y] = t; } diff --git a/src/Message.cs b/src/Message.cs index 794e6f1..1ee3d99 100644 --- a/src/Message.cs +++ b/src/Message.cs @@ -2,7 +2,7 @@ namespace WorldOfPeacecraft { - public class Message + public class Message : IChatMessage { int sourceID; string source; @@ -14,6 +14,21 @@ namespace WorldOfPeacecraft source = src; text = txt; } + + public string GetMessage() + { + return text; + } + + public string GetSender() + { + return source; + } + + public bool IsSenderPlayer () + { + return true; + } } } diff --git a/src/Parser.cs b/src/Parser.cs index b470f3f..265ed56 100644 --- a/src/Parser.cs +++ b/src/Parser.cs @@ -49,47 +49,30 @@ namespace WorldOfPeacecraft public const string MessPlayers = "players"; public const string MessDragon = "dragon"; public const string MessMapcell = "cell"; - private Buffer MonsterBuffer; + private Buffer InputBuffer; private Thread ParserThread; private LinkedList Message; private Regex LastLineRegex; - private Backend backend; + private Backend Backend; - public Parser (Buffer b) + public Parser (Backend backend, Buffer buffer) { - MonsterBuffer = b; - ParserThread = new Thread (new ThreadStart (this.RunParser)); - ParserThread.Start(); + InputBuffer = buffer; + Backend = backend; Message = new LinkedList (); LastLineRegex = new Regex ("^end:[0-9]+$"); + ParserThread = new Thread (new ThreadStart (this.RunParser)); } private void RunParser () - {/* + { while (true) { - bool waitRequired = false; - lock (MonsterBuffer) { - if (MonsterBuffer.Count == 0) { - waitRequired = true; - BufferFilledEvent.Reset (); - } - } - if (waitRequired) { - BufferFilledEvent.WaitOne (); - } - lock (Buffer) { - Message.AddLast (Buffer.Dequeue ()); - } + Message.AddLast (InputBuffer.NextLine ()); if (IsCompletePackage ()) { Parse (); } - }*/ + } } - - public Player getDummyPlayer() - { - return DummyPlayer; - } private void Parse () { @@ -188,11 +171,17 @@ namespace WorldOfPeacecraft switch (block.GetName ()) { case MessPlayer: Player player = MapPlayer (block); - backend.removePlayer (player); + lock (Backend) { + Backend.removePlayer (player); + } + Backend.RefreshGui (); break; case MessDragon: Dragon dragon = MapDragon (block); - backend.removeDragon (dragon); + lock (Backend) { + Backend.removeDragon (dragon); + } + Backend.RefreshGui (); break; default: ThrowUnknownBlockException(deleteBlock, block); @@ -215,15 +204,22 @@ namespace WorldOfPeacecraft foreach (Block cell in cellsBlock.GetBlocks()) { map.SetTile(MapMapcell(cell)); } - backend.SetMap(map); + lock (Backend) { + Backend.SetMap (map); + } + Backend.RefreshGui(); } private void ProcessMessage (Block mesBlock) { + // TODO Ausnahmebehandlung von mehrzeiligen Nachrichten? int srcid = mesBlock.GetIntValue (ValueSourceId); string src = mesBlock.GetStringValue (ValueSource); 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) @@ -286,7 +282,6 @@ namespace WorldOfPeacecraft break; default: throw new ParsingException("Invalid type"); // TODO Better message - break; } bool accepted = challengeBlock.GetBoolValue("accepted"); Challenge c = new Challenge(id, type, accepted); @@ -295,12 +290,19 @@ namespace WorldOfPeacecraft private void ProcessPlayer (Block playerBlock) { - backend.SetPlayer(MapPlayer(playerBlock)); + lock (Backend) { + Backend.SetPlayer (MapPlayer (playerBlock)); + } + Backend.RefreshGui (); } 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) @@ -329,34 +331,48 @@ namespace WorldOfPeacecraft private void ProcessEntities (Block entitiesBlock) { - backend.clearDragons (); - backend.clearPlayers (); - foreach (Block entityBlock in entitiesBlock.GetBlocks ()) { - switch (entityBlock.GetName()) { - case MessPlayer: - backend.SetPlayer(MapPlayer(entityBlock)); - break; - case MessDragon: - backend.SetDragon(MapDragon(entityBlock)); - break; - default: - ThrowUnknownBlockException(entitiesBlock, entityBlock); - break; + // This lock can be placed more efficiently. Does it make sense? + lock (Backend) { + Backend.clearDragons (); + Backend.clearPlayers (); + foreach (Block entityBlock in entitiesBlock.GetBlocks ()) { + switch (entityBlock.GetName ()) { + case MessPlayer: + lock (Backend) { + Backend.SetPlayer (MapPlayer (entityBlock)); + } + break; + case MessDragon: + Backend.SetDragon (MapDragon (entityBlock)); + break; + default: + ThrowUnknownBlockException (entitiesBlock, entityBlock); + break; + } } } + Backend.RefreshGui(); } private void ProcessPlayers (Block playersBlock) { - backend.clearPlayers (); - foreach (Block playerBlock in playersBlock.GetBlocks ()) { - backend.SetPlayer(MapPlayer(playerBlock)); + // This lock can be placed more efficiently. Does it make sense? + lock (Backend) { + Backend.clearPlayers (); + foreach (Block playerBlock in playersBlock.GetBlocks ()) { + Backend.SetPlayer (MapPlayer (playerBlock)); + } } + Backend.RefreshGui (); } 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) @@ -440,12 +456,15 @@ namespace WorldOfPeacecraft return LastLineRegex.IsMatch (lastLine); } + public void Start () + { + ParserThread.Start(); + } + public void Stop () { ParserThread.Abort (); } - - private class Block { diff --git a/src/Receiver.cs b/src/Receiver.cs index f2428ff..82a9851 100644 --- a/src/Receiver.cs +++ b/src/Receiver.cs @@ -9,15 +9,14 @@ namespace WorldOfPeacecraft { private TcpClient Client; private StreamReader Reader; - private Buffer KillerBuffer; + private Buffer ReceiverBuffer; private Thread ReceiverThread; public Receiver (TcpClient client, Buffer buffer) { this.Client = client; - this.KillerBuffer = buffer; + this.ReceiverBuffer = buffer; ReceiverThread = new Thread(new ThreadStart(this.doReceive)); - ReceiverThread.Start(); } public string Receive () @@ -29,13 +28,18 @@ namespace WorldOfPeacecraft { this.Reader = new StreamReader (Client.GetStream ()); while (true) { - KillerBuffer.AddToBuffer(Receive()); + ReceiverBuffer.AddLine(Receive()); } } + public void Start() + { + ReceiverThread.Start (); + } + public void Stop() { - ReceiverThread.Abort(); + ReceiverThread.Abort (); } } } diff --git a/src/Sender.cs b/src/Sender.cs index b61dd1e..9453498 100644 --- a/src/Sender.cs +++ b/src/Sender.cs @@ -2,16 +2,21 @@ using System; using System.IO; using System.Net.Sockets; using System.Text; +using System.Threading; namespace WorldOfPeacecraft { public class Sender { private TcpClient Client; + private Buffer Buffer; + private Thread SenderThread; - public Sender (TcpClient client) + public Sender (TcpClient client, Buffer buffer) { this.Client = client; + this.Buffer = buffer; + this.SenderThread = new Thread(new ThreadStart(this.threadStart)); } public void Send (String message) @@ -20,5 +25,22 @@ namespace WorldOfPeacecraft writer.WriteLine (message); writer.Flush (); } + + private void threadStart () + { + while (true) { + Send (Buffer.NextLine()); + } + } + + public void Start() + { + SenderThread.Start(); + } + + public void Stop() + { + SenderThread.Abort(); + } } } \ No newline at end of file diff --git a/src/Tile.cs b/src/Tile.cs index bfe40db..fcc5697 100644 --- a/src/Tile.cs +++ b/src/Tile.cs @@ -5,115 +5,104 @@ namespace WorldOfPeacecraft { public class Tile : ITile { - public int x; - public int y; - public Entity entity; - public bool walkable; - public bool wall; - public bool forest; - public bool huntable; - public bool water; + public int X; + public int Y; + public Entity Entity; + public bool Walkable; + public bool Wall; + public bool Forest; + public bool Huntable; + public bool Water; public Tile (int posX, int posY, bool walkable, bool wall, bool forest, bool huntable, bool water) { - this.setX (posX); - this.setY (posY); - this.setWalkable (walkable); - this.setWall(wall); - this.setForest (forest); - this.setHuntable (huntable); - this.setWater (water); + this.SetX (posX); + this.SetY (posY); + this.SetWalkable (walkable); + this.SetWall(wall); + this.SetForest (forest); + this.SetHuntable (huntable); + 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) - { - this.walkable = walkable; - } - - public bool isWalkable () - { - return walkable; - } - - public void setWall(bool wall) + public void SetWall(bool wall) { - this.wall = wall; + this.Wall = wall; } - public bool isWall() + public bool IsWall() { - return wall; + return Wall; } - - public void setForest (bool forest) + public void SetForest (bool forest) { - this.forest = forest; + this.Forest = forest; } - public bool isForest () + public bool IsForest () { - return forest; + return Forest; } - public void setHuntable (bool huntable) + public void SetHuntable (bool huntable) { - this.huntable = huntable; + this.Huntable = huntable; } - public bool isHuntable () + public bool IsHuntable () { - return huntable; + return Huntable; } - public void setWater (bool water) + public void SetWater (bool water) { - this.water = water; + this.Water = water; } - public bool isWater () + public bool IsWater () { - return water; + return Water; } } } \ No newline at end of file