diff --git a/Commands/building/CmdGlobalBlock.cs b/Commands/building/CustomBlockCommand.cs similarity index 73% rename from Commands/building/CmdGlobalBlock.cs rename to Commands/building/CustomBlockCommand.cs index ce01a0d47..ccda1ef39 100644 --- a/Commands/building/CmdGlobalBlock.cs +++ b/Commands/building/CustomBlockCommand.cs @@ -1,7 +1,7 @@ -/* +/* Copyright 2015 MCGalaxy - Dual-licensed under the Educational Community License, Version 2.0 and + Dual-licensed under the Educational Community License, Version 2.0 and the GNU General Public License, Version 3 (the "Licenses"); you may not use this file except in compliance with the Licenses. You may obtain a copy of the Licenses at @@ -20,17 +20,11 @@ using System.Collections.Generic; namespace MCGalaxy.Commands { - public sealed class CmdGlobalBlock : Command { - - public override string name { get { return "globalblock"; } } - public override string shortcut { get { return "gb"; } } - public override string type { get { return CommandTypes.Building; } } - public override bool museumUsable { get { return true; } } - public override LevelPermission defaultRank { get { return LevelPermission.Admin; } } - public CmdGlobalBlock() { } - static char[] trimChars = {' '}; + public abstract class CustomBlockCommand : Command { - public override void Use(Player p, string message) { + static char[] trimChars = {' '}; + + protected void Execute(Player p, string message, bool global) { string[] parts = message.Split(trimChars, 4); for (int i = 0; i < Math.Min(parts.Length, 3); i++) parts[i] = parts[i].ToLower(); @@ -46,70 +40,66 @@ namespace MCGalaxy.Commands { switch (parts[0]) { case "add": case "create": - AddHandler(p, parts); break; + AddHandler(p, parts, global); break; case "delete": case "remove": - RemoveHandler(p, parts); break; + RemoveHandler(p, parts, global); break; case "list": case "ids": - ListHandler(p, parts); break; + ListHandler(p, parts, global); break; case "abort": Player.SendMessage(p, "Aborted the custom block creation process."); SetBD(p, null); break; case "edit": - EditHandler(p, parts); break; + EditHandler(p, parts, global); break; default: if (GetBD(p) != null) - DefineBlockStep(p, message); + DefineBlockStep(p, message, global); else Help(p); break; } } - int targetId; - void AddHandler(Player p, string[] parts) { + void AddHandler(Player p, string[] parts, bool global) { + string cmd = global ? "/gb" : "/lb"; + int targetId; if (parts.Length >= 2 ) { string id = parts[1]; if (!CheckBlockId(p, id, out targetId)) return; - BlockDefinition def = BlockDefinition.GlobalDefinitions[targetId]; + BlockDefinition[] defs = global ? BlockDefinition.GlobalDefs : p.level.CustomBlockDefs; + BlockDefinition def = defs[targetId]; if (def != null) { Player.SendMessage(p, "There is already a custom block with the id " + id + - ", you must either use a different id or use \"/gb remove " + id + "\""); + ", you must either use a different id or use \"" + cmd + " remove " + id + "\""); return; } } else { - targetId = GetFreeId(); + targetId = GetFreeId(global, p == null ? null : p.level); if (targetId == Block.Zero) { Player.SendMessage(p, "There are no custom block ids left, " + - "you must /gb remove a custom block first."); + "you must " + cmd +" remove a custom block first."); return; } } SetBD(p, new BlockDefinition()); GetBD(p).BlockID = (byte)targetId; - Player.SendMessage(p, "Type '/gb abort' at anytime to abort the creation process."); - Player.SendMessage(p, "Type '/gb revert' to go back a step in the creation process."); - Player.SendMessage(p, "Use '/gb ' to enter arguments for the creation process."); + SetTargetId(p, targetId); + Player.SendMessage(p, "Type '" + cmd + " abort' at anytime to abort the creation process."); + Player.SendMessage(p, "Type '" + cmd + " revert' to go back a step in the creation process."); + Player.SendMessage(p, "Use '" + cmd + " ' to enter arguments for the creation process."); Player.SendMessage(p, "%f----------------------------------------------------------"); SetStep(p, 2); SendStepHelp(p, GetStep(p)); } - byte GetFreeId() { - for (int i = 70; i < 255; i++) { - if (BlockDefinition.GlobalDefinitions[i] == null) - return (byte)i; - } - return Block.Zero; - } - - void ListHandler(Player p, string[] parts) { + void ListHandler(Player p, string[] parts, bool global) { int offset = 0, index = 0, count = 0; if (parts.Length > 1) int.TryParse(parts[1], out offset); - BlockDefinition[] defs = BlockDefinition.GlobalDefinitions; + BlockDefinition[] defs = global ? BlockDefinition.GlobalDefs : p.level.CustomBlockDefs; + string cmd = global ? "/gb" : "/lb"; for( int i = 1; i < 256; i++ ) { BlockDefinition def = defs[i]; @@ -121,8 +111,8 @@ namespace MCGalaxy.Commands { Player.SendMessage(p, String.Format(format, def.BlockID, def.Name)); if (count >= 8) { - const string helpFormat = "To see the next set of custom blocks, type %T/gb list {0}"; - Player.SendMessage(p, String.Format(helpFormat, offset + 8)); + const string helpFormat = "To see the next set of custom blocks, type %T{1} list {0}"; + Player.SendMessage(p, String.Format(helpFormat, offset + 8, cmd)); return; } } @@ -130,28 +120,28 @@ namespace MCGalaxy.Commands { } } - void RemoveHandler(Player p, string[] parts) { + void RemoveHandler(Player p, string[] parts, bool global) { if (parts.Length <= 1) { Help(p); return; } int blockID; if (!CheckBlockId(p, parts[1], out blockID)) return; - BlockDefinition def = BlockDefinition.GlobalDefinitions[blockID]; - if (def == null) { - Player.SendMessage(p, "There is no globally defined custom block with that block id."); - Player.SendMessage(p, "Use \"%T/gb list\" %Sto see a list of global custom blocks."); - return; - } + BlockDefinition[] defs = global ? BlockDefinition.GlobalDefs : p.level.CustomBlockDefs; + BlockDefinition def = defs[blockID]; + if (def == null) { MessageNoBlock(p, global); return; } - BlockDefinition.RemoveGlobal(def); - BlockDefinition.SaveGlobal(); + BlockDefinition.Remove(def, defs, p == null ? null : p.level); + BlockDefinition globalDef = BlockDefinition.GlobalDefs[blockID]; + if (!global && globalDef != null) { + BlockDefinition.Add(globalDef, defs, p == null ? null : p.level); + } } - void DefineBlockStep(Player p, string value) { + void DefineBlockStep(Player p, string value, bool global) { string opt = value.ToLower(); int step = GetStep(p); if (opt == "revert" && step > 2) { step--; - SendStepHelp(p, step); + SendStepHelp(p, step); SetStep(p, step); return; } BlockDefinition bd = GetBD(p); @@ -223,19 +213,22 @@ namespace MCGalaxy.Commands { SendStepHelp(p, step); return; } bd.FallBack = Block.Byte(value); + BlockDefinition[] defs = global ? BlockDefinition.GlobalDefs : p.level.CustomBlockDefs; + BlockDefinition def = defs[bd.BlockID]; // in case the list is modified before we finish the command. - if (BlockDefinition.GlobalDefinitions[bd.BlockID] != null) { - bd.BlockID = GetFreeId(); + if (def != null) { + bd.BlockID = GetFreeId(global, p == null ? null : p.level); if (bd.BlockID == Block.Zero) { + string cmd = global ? "/gb" : "/lb"; Player.SendMessage(p, "There are no custom block ids left, " + - "you must /gb remove a custom block first."); + "you must " + cmd + " remove a custom block first."); return; } } Player.SendMessage(p, "Created a new custom block " + bd.Name + "(" + bd.BlockID + ")"); - BlockDefinition.AddGlobal(bd); + BlockDefinition.Add(bd, defs, p == null ? null : p.level); SetBD(p, null); SetStep(p, 0); return; @@ -244,23 +237,7 @@ namespace MCGalaxy.Commands { SetStep(p, step); } - bool EditByte(Player p, string arg, string propName, ref byte target) { - return EditByte(p, arg, propName, ref target, -1, 0, 0, 255); - } - - bool EditByte(Player p, string value, string propName, ref byte target, - int step, int offset, byte min, byte max) { - int temp = 0; - if (!int.TryParse(value, out temp) || temp < min || temp > max) { - Player.SendMessage(p, propName + " must be an integer between " + min + " and " + max + "."); - if (step != -1) SendEditHelp(p, step, offset); - return false; - } - target = (byte)temp; - return true; - } - - void EditHandler(Player p, string[] parts) { + void EditHandler(Player p, string[] parts, bool global) { if (parts.Length <= 3) { if(parts.Length == 1) Player.SendMessage(p, "Valid properties: name, collide, speed, toptex, sidetex, " + @@ -271,14 +248,11 @@ namespace MCGalaxy.Commands { return; } int blockId; - if (!CheckBlockId(p, parts[1], out blockId)); + if (!CheckBlockId(p, parts[1], out blockId)) return; + BlockDefinition[] defs = global ? BlockDefinition.GlobalDefs : p.level.CustomBlockDefs; + BlockDefinition def = defs[blockId]; + if (def == null) { MessageNoBlock(p, global); return; } - BlockDefinition def = BlockDefinition.GlobalDefinitions[blockId]; - if (def == null) { - Player.SendMessage(p, "There is no globally defined custom block with that block id."); - Player.SendMessage(p, "Use \"%T/gb list\" %Sto see a list of global custom blocks."); - return; - } string value = parts[3]; float fTemp; byte tempX, tempY, tempZ; @@ -373,14 +347,47 @@ namespace MCGalaxy.Commands { def.FallBack = tempX; break; } - BlockDefinition.AddGlobal(def); + BlockDefinition.Add(def, defs, p == null ? null : p.level); foreach (Player pl in Player.players) { if (!pl.HasCpeExt(CpeExt.BlockDefinitions)) continue; if (pl.level == null || !pl.level.HasCustomBlocks) continue; + if (!global && p.level != pl.level) continue; + Command.all.Find("reveal").Use(p, pl.name); } } + static byte GetFreeId(bool global, Level lvl) { + BlockDefinition[] defs = global ? BlockDefinition.GlobalDefs : lvl.CustomBlockDefs; + for (int i = 70; i < 255; i++) { + if (defs[i] == null) return (byte)i; + } + return Block.Zero; + } + + static void MessageNoBlock(Player p, bool global) { + string scope = global ? "global" : "level"; + string cmd = global ? "/gb" : "/lb"; + Player.SendMessage(p, "There is no " + scope + " custom block with that block id."); + Player.SendMessage(p, "Type \"%T" + cmd +" list\" %Sto see a list of " + scope + " custom blocks."); + } + + static bool EditByte(Player p, string arg, string propName, ref byte target) { + return EditByte(p, arg, propName, ref target, -1, 0, 0, 255); + } + + static bool EditByte(Player p, string value, string propName, ref byte target, + int step, int offset, byte min, byte max) { + int temp = 0; + if (!int.TryParse(value, out temp) || temp < min || temp > max) { + Player.SendMessage(p, propName + " must be an integer between " + min + " and " + max + "."); + if (step != -1) SendEditHelp(p, step, offset); + return false; + } + target = (byte)temp; + return true; + } + static bool ParseCoords(string parts, out byte x, out byte y, out byte z) { x = 0; y = 0; z = 0; string[] coords = parts.Split(' '); @@ -459,28 +466,69 @@ namespace MCGalaxy.Commands { static BlockDefinition consoleBD; static int consoleStep = 0; + static int consoleTargetId; - static BlockDefinition GetBD(Player p) { return p == null ? consoleBD : p.gbBlock; } + static BlockDefinition GetBD(Player p) { return p == null ? consoleBD : p.bdBlock; } static void SetBD(Player p, BlockDefinition bd) { if (p == null) consoleBD = bd; - else p.gbBlock = bd; + else p.bdBlock = bd; } - - static int GetStep(Player p) { return p == null ? consoleStep : p.gbStep; } + + static void SetTargetId(Player p, int targetId) { + if (p == null) consoleTargetId = targetId; + else p.bdTargetId = targetId; + } + + static int GetStep(Player p) { return p == null ? consoleStep : p.bdStep; } static void SetStep(Player p, int step) { if (p == null) consoleStep = step; - else p.gbStep = step; + else p.bdStep = step; } - public override void Help(Player p) { - Player.SendMessage(p, "%T/globalblock "); - Player.SendMessage(p, "%H /gb add [id] - begins the creation a new custom block."); - Player.SendMessage(p, "%H /gb remove id - removes the custom block with the given id."); - Player.SendMessage(p, "%H /gb list [offset] - lists all custom blocks."); - Player.SendMessage(p, "%H /gb edit id property value - edits the given property of the custom block with the given id."); - Player.SendMessage(p, "%HTo see the list of editable properties, type /gb edit."); + protected static void Help(Player p, bool global) { + string fullCmd = global ? "/globalblock" : "/levelblock"; + string cmd = global ? "/gb" : "/lb"; + + Player.SendMessage(p, "%T" + fullCmd + " "); + Player.SendMessage(p, "%H " + cmd + " add [id] - begins the creation a new custom block."); + Player.SendMessage(p, "%H " + cmd + " remove id - removes the custom block with the given id."); + Player.SendMessage(p, "%H " + cmd + " list [offset] - lists all custom blocks."); + Player.SendMessage(p, "%H " + cmd + " edit id property value - edits the given property of the custom block with the given id."); + Player.SendMessage(p, "%HTo see the list of editable properties, type " + cmd + " edit."); } } + + public sealed class CmdGlobalBlock : CustomBlockCommand { + + public override string name { get { return "globalblock"; } } + public override string shortcut { get { return "gb"; } } + public override string type { get { return CommandTypes.Building; } } + public override bool museumUsable { get { return true; } } + public override LevelPermission defaultRank { get { return LevelPermission.Admin; } } + public CmdGlobalBlock() { } + + public override void Use(Player p, string message) { + Execute(p, message, true); + } + + public override void Help(Player p) { Help(p, true); } + } + + public sealed class CmdLevelBlock : CustomBlockCommand { + + public override string name { get { return "levelblock"; } } + public override string shortcut { get { return "lb"; } } + public override string type { get { return CommandTypes.Building; } } + public override bool museumUsable { get { return true; } } + public override LevelPermission defaultRank { get { return LevelPermission.Admin; } } + public CmdLevelBlock() { } + + public override void Use(Player p, string message) { + Execute(p, message, false); + } + + public override void Help(Player p) { Help(p, false); } + } } \ No newline at end of file diff --git a/Commands/building/DrawCmd.cs b/Commands/building/DrawCmd.cs index 3e591fdef..71421fea0 100644 --- a/Commands/building/DrawCmd.cs +++ b/Commands/building/DrawCmd.cs @@ -92,7 +92,7 @@ namespace MCGalaxy.Commands { extType = 0; if (type == Block.Zero) { // try treat as a block definition id. - type = BlockDefinition.GetBlock(msg); + type = BlockDefinition.GetBlock(msg, p); if (type == Block.Zero) { Player.SendMessage(p, "There is no block \"" + msg + "\"."); return Block.Zero; diff --git a/Levels/BlockDefinitions.cs b/Levels/BlockDefinitions.cs index c6fde2bf7..60d6d2629 100644 --- a/Levels/BlockDefinitions.cs +++ b/Levels/BlockDefinitions.cs @@ -36,26 +36,20 @@ namespace MCGalaxy { public bool FullBright; public byte Shape; public byte BlockDraw; - public byte FogDensity,FogR, FogG, FogB; - public byte FallBack; + public byte FogDensity,FogR, FogG, FogB; + public byte FallBack; // BlockDefinitionsExt fields public byte MinX, MinY, MinZ; public byte MaxX, MaxY, MaxZ; public const string GlobalPath = "blockdefs/global.json", GlobalBackupPath = "blockdefs/global.json.bak"; - public static BlockDefinition[] GlobalDefinitions = new BlockDefinition[256]; + public static BlockDefinition[] GlobalDefs; public static void LoadGlobal() { - try { - if (File.Exists(GlobalPath)) { - string json = File.ReadAllText(GlobalPath); - GlobalDefinitions = JsonConvert.DeserializeObject(json); - } - } catch (Exception ex) { - Server.ErrorLog(ex); - GlobalDefinitions = new BlockDefinition[256]; - } - + GlobalDefs = Load(true, null); + GlobalDefs[0] = new BlockDefinition(); + GlobalDefs[0].Name = "Air fallback"; + try { if (File.Exists(GlobalBackupPath)) File.Delete(GlobalBackupPath); @@ -63,25 +57,52 @@ namespace MCGalaxy { } catch (Exception ex) { Server.ErrorLog(ex); } + Save(true, null); + } + + static BlockDefinition[] Load(bool global, Level lvl) { + BlockDefinition[] defs = new BlockDefinition[256]; + string path = global ? GlobalPath : "blockdefs/" + lvl.name; + try { + if (File.Exists(GlobalPath)) { + string json = File.ReadAllText(GlobalPath); + defs = JsonConvert.DeserializeObject(json); + } + } catch (Exception ex) { + Server.ErrorLog(ex); + defs = new BlockDefinition[256]; + } for (int i = 0; i < 256; i++) { - if (GlobalDefinitions[i] != null && GlobalDefinitions[i].Name == null) - GlobalDefinitions[i] = null; - } - GlobalDefinitions[0] = new BlockDefinition(); - GlobalDefinitions[0].Name = "Air fallback"; - SaveGlobal(); + if (defs[i] != null && defs[i].Name == null) + defs[i] = null; + } + return defs; } - public static void SaveGlobal() { - string json = JsonConvert.SerializeObject(GlobalDefinitions); - File.WriteAllText(GlobalPath, json); + static void Save(bool global, Level lvl) { + BlockDefinition[] defs = global ? GlobalDefs : lvl.CustomBlockDefs; + string json = JsonConvert.SerializeObject(defs); + string path = global ? GlobalPath : "blockdefs/" + lvl.name; + File.WriteAllText(path, json); } - public static void AddGlobal(BlockDefinition def) { - GlobalDefinitions[def.BlockID] = def; + public static void Add(BlockDefinition def, BlockDefinition[] defs, Level level) { + byte id = def.BlockID; + bool global = defs == GlobalDefs; + if (global) { + foreach (Level lvl in Server.levels) { + if (lvl.CustomBlockDefs[id] == null) + lvl.CustomBlockDefs[id] = def; + } + } + defs[id] = def; + foreach (Player pl in Player.players) { - if (!pl.HasCpeExt(CpeExt.BlockDefinitions)) continue; + if (!global && pl.level != level) continue; + if (!pl.HasCpeExt(CpeExt.BlockDefinitions)) continue; + if (global && pl.level.CustomBlockDefs[id] != GlobalDefs[id]) continue; + if (pl.HasCpeExt(CpeExt.BlockDefinitionsExt) && def.Shape != 0) SendDefineBlockExt(pl, def); else @@ -90,23 +111,33 @@ namespace MCGalaxy { if (pl.HasCpeExt(CpeExt.BlockPermissions)) pl.SendSetBlockPermission(def.BlockID, pl.level.Buildable, pl.level.Deletable); } - SaveGlobal(); + Save(global, level); } - public static void RemoveGlobal(BlockDefinition def) { - GlobalDefinitions[def.BlockID] = null; - foreach (Player p in Player.players) { - if (p.HasCpeExt(CpeExt.BlockDefinitions)) - p.SendRaw(Opcode.CpeRemoveBlockDefinition, def.BlockID); + public static void Remove(BlockDefinition def, BlockDefinition[] defs, Level level) { + byte id = def.BlockID; + bool global = defs == GlobalDefs; + if (global) { + foreach (Level lvl in Server.levels) { + if (lvl.CustomBlockDefs[id] == GlobalDefs[id]) + lvl.CustomBlockDefs[id] = null; + } } - SaveGlobal(); + defs[id] = null; + + foreach (Player pl in Player.players) { + if (!global && pl.level != level) continue; + if (pl.HasCpeExt(CpeExt.BlockDefinitions)) + pl.SendRaw(Opcode.CpeRemoveBlockDefinition, id); + } + Save(global, level); } - public static void SendAll(Player pl) { - if (!pl.HasCpeExt(CpeExt.BlockDefinitions)) return; - for (int i = 1; i < GlobalDefinitions.Length; i++) { - BlockDefinition def = GlobalDefinitions[i]; - if (def == null) continue; + internal static void SendLevelCustomBlocks(Player pl) { + BlockDefinition[] defs = pl.level.CustomBlockDefs; + for (int i = 1; i < defs.Length; i++) { + BlockDefinition def = defs[i]; + if (def == null) continue; if (pl.HasCpeExt(CpeExt.BlockDefinitionsExt) && def.Shape != 0) SendDefineBlockExt(pl, def); else @@ -117,9 +148,10 @@ namespace MCGalaxy { } } - public static byte GetBlock(string msg) { - for (int i = 1; i < 255; i++) { - BlockDefinition def = GlobalDefinitions[i]; + public static byte GetBlock(string msg, Player p) { + BlockDefinition[] defs = p.level.CustomBlockDefs; + for (int i = 1; i < 255; i++) { + BlockDefinition def = defs[i]; if (def == null) continue; if (def.Name.Replace(" ", "").Equals(msg, StringComparison.OrdinalIgnoreCase)) @@ -127,16 +159,11 @@ namespace MCGalaxy { } byte type; - if (!byte.TryParse(msg, out type) || BlockDefinition.GlobalDefinitions[type] == null) + if (!byte.TryParse(msg, out type) || defs[type] == null) return Block.Zero; return type; } - public static byte Fallback(byte tile) { - BlockDefinition def = GlobalDefinitions[tile]; - return def == null ? Block.air : def.FallBack; - } - static void SendDefineBlock(Player p, BlockDefinition def) { byte[] buffer = new byte[80]; buffer[0] = Opcode.CpeDefineBlock; diff --git a/Levels/Level.Blocks.cs b/Levels/Level.Blocks.cs index 0426e75e6..30711781d 100644 --- a/Levels/Level.Blocks.cs +++ b/Levels/Level.Blocks.cs @@ -68,6 +68,23 @@ namespace MCGalaxy { chunk[(y & 0x0F) << 8 | (z & 0x0F) << 4 | (x & 0x0F)]; } + public byte GetFallbackExtTile(ushort x, ushort y, ushort z) { + byte tile = GetExtTile(x, y, z); + BlockDefinition def = CustomBlockDefs[tile]; + return def == null ? Block.air : def.FallBack; + } + + public byte GetFallbackExtTile(int index) { + byte tile = GetExtTile(index); + BlockDefinition def = CustomBlockDefs[tile]; + return def == null ? Block.air : def.FallBack; + } + + public byte GetFallback(byte extType) { + BlockDefinition def = CustomBlockDefs[extType]; + return def == null ? Block.air : def.FallBack; + } + public void SetTile(int b, byte type) { if (blocks == null || b < 0 || b >= blocks.Length) return; blocks[b] = type; diff --git a/Levels/Level.cs b/Levels/Level.cs index 9188a0766..488919590 100644 --- a/Levels/Level.cs +++ b/Levels/Level.cs @@ -152,6 +152,9 @@ namespace MCGalaxy /// The block which will be displayed on the edge of the map. public byte EdgeBlock = Block.blackrock; + + public BlockDefinition[] CustomBlockDefs; + public ushort jailx, jaily, jailz; public int lastCheck; public int lastUpdate; @@ -216,6 +219,9 @@ namespace MCGalaxy if (Length < 16) Length = 16; + CustomBlockDefs = new BlockDefinition[256]; + for (int i = 0; i < CustomBlockDefs.Length; i++) + CustomBlockDefs[i] = BlockDefinition.GlobalDefs[i]; name = n; EdgeLevel = (short)(y / 2); CloudsHeight = (short)(y + 2); diff --git a/MCGalaxy_.csproj b/MCGalaxy_.csproj index a51d45b7d..fd8bbc555 100644 --- a/MCGalaxy_.csproj +++ b/MCGalaxy_.csproj @@ -98,7 +98,6 @@ - @@ -134,6 +133,7 @@ + diff --git a/Network/Player.Networking.cs b/Network/Player.Networking.cs index d0041c356..1214abaf7 100644 --- a/Network/Player.Networking.cs +++ b/Network/Player.Networking.cs @@ -74,7 +74,7 @@ namespace MCGalaxy { } } - public bool hasCpe = false, hasCustomBlocks = false, hasTextColors, finishedLogin = false; + public bool hasCpe = false, hasCustomBlocks = false, hasTextColors, finishedCpeLogin = false; public string appName; public int extensionCount; public List extensions = new List(); @@ -90,21 +90,13 @@ namespace MCGalaxy { } void HandleExtEntry( byte[] message ) { - AddExtension(enc.GetString(message, 0, 64).Trim(), NTHO_Int(message, 64)); + AddExtension(enc.GetString(message, 0, 64).Trim(), NetUtils.ReadI32(message, 64)); extensionCount--; - if (extensionCount <= 0 && !finishedLogin) { - if (HasCpeExt(CpeExt.BlockDefinitions) || HasCpeExt(CpeExt.BlockDefinitionsExt)) - BlockDefinition.SendAll(this); + if (extensionCount <= 0 && !finishedCpeLogin) { CompleteLoginProcess(); - finishedLogin = true; + finishedCpeLogin = true; } } - public static int NTHO_Int(byte[] x, int offset) - { - byte[] y = new byte[4]; - Buffer.BlockCopy(x, offset, y, 0, 4); Array.Reverse(y); - return BitConverter.ToInt32(y, 0); - } void HandleCustomBlockSupportLevel( byte[] message ) { customBlockSupportLevel = message[0]; @@ -317,7 +309,7 @@ namespace MCGalaxy { if (hasBlockDefinitions) buffer[i + 4] = level.GetExtTile(i); else - buffer[i + 4] = BlockDefinition.Fallback(level.GetExtTile(i)); + buffer[i + 4] = level.GetFallbackExtTile(i); } else { buffer[i + 4] = Block.Convert(block); } @@ -329,8 +321,7 @@ namespace MCGalaxy { if (hasBlockDefinitions) buffer[i + 4] = Block.ConvertCPE(level.GetExtTile(i)); else - buffer[i + 4] = Block.ConvertCPE( - BlockDefinition.Fallback(level.GetExtTile(i))); + buffer[i + 4] = Block.ConvertCPE(level.GetFallbackExtTile(i)); } else { buffer[i + 4] = Block.Convert(Block.ConvertCPE(level.blocks[i])); } @@ -370,6 +361,8 @@ namespace MCGalaxy { SendCurrentEnvColors(); if (HasCpeExt(CpeExt.EnvMapAppearance) || HasCpeExt(CpeExt.EnvMapAppearance, 2)) SendCurrentMapAppearance(); + if (HasCpeExt(CpeExt.BlockDefinitions)) + BlockDefinition.SendLevelCustomBlocks(this); if ( OnSendMap != null ) OnSendMap(this, buffer); if (!level.guns) @@ -452,7 +445,7 @@ namespace MCGalaxy { if (HasCpeExt(CpeExt.BlockDefinitions)) buffer[7] = level.GetExtTile(x, y, z); else - buffer[7] = BlockDefinition.Fallback(level.GetExtTile(x, y, z)); + buffer[7] = level.GetFallbackExtTile(x, y, z); } else if (hasCustomBlocks) { buffer[7] = Block.Convert(type); } else { @@ -476,7 +469,7 @@ namespace MCGalaxy { if (HasCpeExt(CpeExt.BlockDefinitions)) buffer[7] = extType; else - buffer[7] = BlockDefinition.Fallback(extType); + buffer[7] = level.GetFallback(extType); } else if (hasCustomBlocks) { buffer[7] = Block.Convert(type); } else { diff --git a/Player/Player.CPE.cs b/Player/Player.CPE.cs index da7ff5d62..c6b21917e 100644 --- a/Player/Player.CPE.cs +++ b/Player/Player.CPE.cs @@ -234,7 +234,7 @@ namespace MCGalaxy if (!HasCpeExt(CpeExt.BlockDefinitions)) return; for (int i = count; i < 256; i++) { - if (BlockDefinition.GlobalDefinitions[i] == null) continue; + if (level.CustomBlockDefs[i] == null) continue; SendSetBlockPermission((byte)i, level.Buildable, level.Deletable); } } diff --git a/Player/Player.cs b/Player/Player.cs index db2f61f5a..87edd6396 100644 --- a/Player/Player.cs +++ b/Player/Player.cs @@ -230,8 +230,9 @@ namespace MCGalaxy { public int[] centerend = new int[3] { 0, 0, 0 }; // GlobalBlock - internal int gbStep = 0; - internal BlockDefinition gbBlock; + internal int bdStep = 0; + internal int bdTargetId = 0; + internal BlockDefinition bdBlock; public string model = "humanoid"; public bool spawned = false; @@ -1055,8 +1056,7 @@ namespace MCGalaxy { } if (type >= Block.CpeCount) { - if (!HasCpeExt(CpeExt.BlockDefinitions) - || BlockDefinition.GlobalDefinitions[type] == null) { + if (!HasCpeExt(CpeExt.BlockDefinitions) || level.CustomBlockDefs[type] == null) { SendMessage("Invalid block type: " + type); return; } extType = type;