Skip to content

Instantly share code, notes, and snippets.

@monoclex
Created January 12, 2019 18:00
Show Gist options
  • Save monoclex/7d3c0d6670aef97807c09e139e9e136b to your computer and use it in GitHub Desktop.
Save monoclex/7d3c0d6670aef97807c09e139e9e136b to your computer and use it in GitHub Desktop.
A better version of atilla's World.cs
using Ceras;
using PlayerIOClient;
using SixLabors.ImageSharp.PixelFormats;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class World : PropertyEnumerable
{
public World(byte[] serialied) : base(serialied)
=> Blocks = Properties["worlddata"].GetAsBlocks();
public World(PropertyEnumerable propertyEnumerable, string worldId) : base(propertyEnumerable.Properties)
{
Properties["worldId"] = worldId;
Blocks = Properties["worlddata"].GetAsBlocks();
}
public string WorldId => Get<string>("worldId", "PW_UNKOWN_EI");
public string Name => Get<string>("name", "Untitled World");
public string Owner => Get<string>("owner");
public string Crew => Get<string>("Crew");
public string Description => Get<string>("worldDescription");
public int Type => Get<int>("type");
public int Width => Get<int>("width", 200);
public int Height => Get<int>("height", 200);
public int Plays => Get<int>("plays");
public int Woots => Get<int>("woots");
public int TotalWoots => Get<int>("totalwoots");
public int Likes => Get<int>("Likes");
public int Favorites => Get<int>("Favorites");
public bool Visible => Get<bool>("visible", Settings.VisibleShouldBe);
public bool HideLobby => Get<bool>("HideLobby", Settings.HideLobbyShouldBe);
public bool MinimapEnabled => Get<bool>("MinimapEnabled", Settings.MinimapEnabledShouldBe);
[Obsolete("Potions are no longer available.")]
public bool AllowPotions => Get<bool>("allowpotions");
public Rgba32 BackgroundColor => Get<uint>("backgroundColor", 0xFF000000).ToRgba32();
public Block[] Blocks { get; }
}
public class Block : PropertyEnumerable
{
public Block(PropertyEnumerable enumerable, Location[] locations)
{
Properties = enumerable.Properties;
Locations = locations;
}
public uint Type => Get<uint>("type");
public int Layer => Get<int>("layer");
public int Rotation => Get<int>("rotation");
public int Goal => Get<int>("goal");
public object Id => Get<object>("id");
public object Target => Get<object>("target");
public string Text => Get<string>("text");
public int SignType => Get<int>("signtype");
public string Name => Get<string>("name");
public string TextMessage1 => Get<string>("mes1");
public string TextMessage2 => Get<string>("mes2");
public string TextMessage3 => Get<string>("mes3");
public Location[] Locations { get; }
public class Location
{
public Location(int x, int y)
{
X = x;
Y = y;
}
public int X { get; }
public int Y { get; }
}
}
public class PropertyEnumerable : IEnumerable<KeyValuePair<string, object>>
{
public PropertyEnumerable() => Properties = new Dictionary<string, object>();
public PropertyEnumerable(Dictionary<string, object> properties)
=> Properties = properties ?? throw new ArgumentNullException(nameof(properties));
public PropertyEnumerable(byte[] serialized)
=> Properties = serialized.Deserialize();
public Dictionary<string, object> Properties { get; protected set; }
public object this[string key]
{
get => Properties.TryGetValue(key, out var result) ? result : default;
set => Properties[key] = value;
}
public T Get<T>(string key, T defaultValue = default)
=> Properties.TryGetValue(key, out var result) ?
(T)result
: defaultValue;
public IEnumerator<KeyValuePair<string, object>> GetEnumerator() => Properties.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => Properties.GetEnumerator();
}
public static class HelperExtensions
{
public static CerasSerializer CerasSerializerSingleton { get; } = new CerasSerializer();
public static PropertyEnumerable ToPropertyEnumerable(this DatabaseObject dbo) => new PropertyEnumerable(dbo.ToDictionary());
public static Dictionary<string, object> ToDictionary(this DatabaseObject dbo)
=> dbo.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToStandardObject());
public static object[] ToArray(this DatabaseArray dba)
=> dba.Select(x => x.ToStandardObject()).ToArray();
public static object ToStandardObject(this object value)
{
switch (value)
{
case var _ when value is DatabaseObject valDbo: return valDbo.ToDictionary();
case var _ when value is DatabaseArray valDba: return valDba.ToArray();
default: return value;
}
}
public static Rgba32 ToRgba32(this uint color)
=> new Rgba32
(
r: (byte)(color >> 16 & 255),
g: (byte)(color >> 8 & 255),
b: (byte)(color & 255),
a: (byte)(color >> 24 & 255)
);
public static Block[] GetAsBlocks(this object obj)
{
if (!(obj is object[] objects))
{
return new Block[0];
}
var blocks = new Block[objects.Length];
for (int i = 0; i < blocks.Length; i++)
{
var propertyEnumerable = new PropertyEnumerable(objects[i].GetAsDictionary<string, object>());
byte[] x = propertyEnumerable.Get("x", new byte[0]), x1 = propertyEnumerable.Get("x1", new byte[0]),
y = propertyEnumerable.Get("y", new byte[0]), y1 = propertyEnumerable.Get("y1", new byte[0]);
var locations = new Block.Location[(x.Length / 2) + x1.Length];
for (int j = 0; j < x.Length; j += 2)
{
locations[j / 2] = new Block.Location((x[j] << 8) + x[j + 1], (y[j] << 8) + y[j + 1]);
}
for (int j = 0; j < x1.Length; j++)
{
locations[j + (x.Length / 2)] = new Block.Location(x1[j], y1[j]);
}
blocks[i] = new Block(propertyEnumerable, locations);
}
return blocks;
}
public static Dictionary<TKey, TValue> GetAsDictionary<TKey, TValue>(this object obj)
=> obj is Dictionary<object, object> objDict ?
objDict.ToDictionary(kvp => (TKey)kvp.Key, kvp => (TValue)kvp.Value)
: obj is Dictionary<TKey, TValue> returnVal ?
returnVal
: throw new Exception($"Unknown kind of dictionary ({obj.GetType()})");
public static byte[] Serialize(this PropertyEnumerable dict) => CerasSerializerSingleton.Serialize(dict.Properties);
public static Dictionary<string, object> Deserialize(this byte[] bytes) => CerasSerializerSingleton.Deserialize<Dictionary<string, object>>(bytes);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment