Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using PlayerIOClient;
- namespace WorldData
- {
- public class World
- {
- public struct Block
- {
- public Block(uint id, uint placer = 0, object[] data = null)
- {
- if (data == null) { data = new Object[] { }; }
- this.Id = id;
- this.Extra = data;
- this.Placer = placer;
- }
- /// <summary>
- /// ID of the block.
- /// </summary>
- public uint Id { get; set; }
- /// <summary>
- /// Extra data for block (sign text, rotation, portal ids etc)
- /// </summary>
- public object[] Extra { get; set; }
- /// <summary>
- /// ID of the player that placed this block.
- /// </summary>
- public uint Placer { get; set; }
- }
- /// <summary>
- /// World/Block Data in format; x, y, z(layer) (0 foreground, 1 background)
- /// </summary>
- public Block[,,] Data { get; private set; }
- /// <summary>
- /// Size of the world.
- /// </summary>
- public Point Size { get; private set; }
- /// <summary>
- /// Username of world owner.
- /// </summary>
- public string Ownername { get; private set; }
- /// <summary>
- /// Name of the world.
- /// </summary>
- public string Name { get; private set; }
- /// <summary>
- /// World plays.
- /// </summary>
- public int Plays { get; private set; }
- /// <summary>
- /// World likes.
- /// </summary>
- public int Likes { get; private set; }
- /// <summary>
- /// World favorites.
- /// </summary>
- public int Favorites { get; private set; }
- /// <summary>
- /// Parses PlayerIO Message. Put "world.Parse(Message);" at the beginning of OnMessage event.
- /// </summary>
- public void Parse(Message m)
- {
- switch (m.Type)
- {
- case "init":
- UpdateMeta(m.GetString(0), m.GetString(1), m.GetInt(2), m.GetInt(3), m.GetInt(4));
- this.Size = new Point(m.GetInt(18), m.GetInt(19));
- Clear(m);
- Deserialize(m);
- break;
- case "reset":
- Clear(m);
- Deserialize(m);
- break;
- case "updatemeta":
- UpdateMeta(m.GetString(0), m.GetString(1), m.GetInt(2), m.GetInt(3), m.GetInt(4));
- break;
- #region parse placed blocks
- case "b": // normal block
- this.Data[m.GetInt(1), m.GetInt(2), m.GetInt(0)] = new Block(m.GetUInt(3), m.GetUInt(4));
- break;
- case "bc": // block with number value
- this.Data[m.GetInt(0), m.GetInt(1), 0] = new Block(m.GetUInt(2), m.GetUInt(4), new Object[] { m.GetUInt(3) });
- break;
- case "br": // block with rotation
- this.Data[m.GetInt(0), m.GetInt(1), m.GetInt(4)] = new Block(m.GetUInt(2), m.GetUInt(5), new Object[] { m.GetUInt(3) });
- break;
- case "bs": // music block
- this.Data[m.GetInt(0), m.GetInt(1), 0] = new Block(m.GetUInt(2), m.GetUInt(4), new Object[] { m.GetUInt(3) });
- break;
- case "pt": // portal block
- this.Data[m.GetInt(0), m.GetInt(1), 0] = new Block(m.GetUInt(2), (uint)m.GetInt(6), new Object[] { m.GetUInt(3), m.GetUInt(4), m.GetUInt(5) });
- break;
- case "ts": //.. sign block
- this.Data[m.GetInt(0), m.GetInt(1), 0] = new Block(m.GetUInt(2), m.GetUInt(5), new Object[] { m.GetString(3), m.GetUInt(4) });
- break;
- case "wp": //... world portal
- this.Data[m.GetInt(0), m.GetInt(1), 0] = new Block(m.GetUInt(2), m.GetUInt(4), new Object[] { m.GetString(3) });
- break;
- case "lb": // label block
- this.Data[m.GetInt(0), m.GetInt(1), 0] = new Block(m.GetUInt(2), m.GetUInt(5), new Object[] { m.GetString(3), m.GetString(4) });
- break;
- #endregion
- case "clear":
- Clear(m);
- break;
- }
- }
- #region deserializer
- private void Clear(Message m)
- {
- uint b = m.Type == "clear" ? m.GetUInt(2) : /*9*/0, f = m.Type == "clear" ? m.GetUInt(3) : 0; // aahhhhhhhhhhh
- this.Data = new Block[this.Size.X, this.Size.Y, 2];
- int x = 0, y = 0;
- for (x = 0; x < this.Size.X; x++)
- {
- for (y = 0; y < this.Size.Y; y++)
- {
- this.Data[x, y, 1] = new Block(0);
- if (x == 0 || x == this.Size.X - 1 || y == 0 || y == this.Size.Y - 1) { this.Data[x, y, 0] = new Block(b); } // check for borders
- else { this.Data[x, y, 0] = new Block(f); }
- }
- }
- }
- private void Deserialize(Message m)
- {
- var chunks = InitParse.Parse(m);
- foreach (var chunk in chunks)
- {
- foreach (var pos in chunk.Locations)
- {
- this.Data[pos.X, pos.Y, chunk.Layer] = new Block(chunk.Type, 0, chunk.Args);
- }
- }
- }
- private static class InitParse
- { // made by processor // https://gist.github.com/Yonom/3c9ebfe69b1432452f9b // thx <3
- public static DataChunk[] Parse(Message m)
- {
- if (m == null) throw new ArgumentNullException("m");
- if (m.Type != "init" && m.Type != "reset") throw new ArgumentException("Invalid message type.", "m");
- // Get world data
- var p = 0u;
- var data = new Stack<object>();
- while (m[p++] as string != "ws") { }
- while (m[p] as string != "we") { data.Push(m[p++]); }
- // Parse world data
- var chunks = new List<DataChunk>();
- while (data.Count > 0)
- {
- var args = new Stack<object>();
- while (!(data.Peek() is byte[]))
- args.Push(data.Pop());
- var ys = (byte[])data.Pop();
- var xs = (byte[])data.Pop();
- var layer = (int)data.Pop();
- var type = (uint)data.Pop();
- chunks.Add(new DataChunk(layer, type, xs, ys, args.ToArray()));
- }
- return chunks.ToArray();
- }
- public class DataChunk
- {
- public int Layer { get; set; }
- public uint Type { get; set; }
- public Point[] Locations { get; set; }
- public object[] Args { get; set; }
- public DataChunk(int layer, uint type, byte[] xs, byte[] ys, object[] args)
- {
- this.Layer = layer;
- this.Type = type;
- this.Args = args;
- this.Locations = GetLocations(xs, ys);
- }
- private static Point[] GetLocations(byte[] xs, byte[] ys)
- {
- var points = new List<Point>();
- for (var i = 0; i < xs.Length; i += 2)
- points.Add(new Point(
- (xs[i] << 8) | xs[i + 1],
- (ys[i] << 8) | ys[i + 1]));
- return points.ToArray();
- }
- }
- }
- #endregion
- private void UpdateMeta(string owner, string name, int plays, int favs, int likes)
- {
- this.Ownername = owner;
- this.Name = name;
- this.Plays = plays;
- this.Favorites = favs;
- this.Likes = likes;
- }
- }
- public struct Point
- {
- public int X { get; set; }
- public int Y { get; set; }
- public Point(int x, int y) : this()
- {
- this.X = x;
- this.Y = y;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement