diff --git a/MCGalaxy/Commands/CPE/CmdEnvironment.cs b/MCGalaxy/Commands/CPE/CmdEnvironment.cs index 5de90adc3..e61acac7e 100644 --- a/MCGalaxy/Commands/CPE/CmdEnvironment.cs +++ b/MCGalaxy/Commands/CPE/CmdEnvironment.cs @@ -52,7 +52,7 @@ public override void Use(Player p, string message, CommandData data) { if (!LevelInfo.Check(p, data.Rank, lvl, "set env settings of this level")) return; } - string[] args = message.SplitSpaces(); + string[] args = message.SplitSpaces(2); string opt = args[0], value = args.Length > 1 ? args[1] : ""; if (!Handle(p, lvl, opt, value, cfg, area)) { Help(p); } } diff --git a/MCGalaxy/Commands/Information/CmdMapInfo.cs b/MCGalaxy/Commands/Information/CmdMapInfo.cs index eae5d6c1e..9abb5797a 100644 --- a/MCGalaxy/Commands/Information/CmdMapInfo.cs +++ b/MCGalaxy/Commands/Information/CmdMapInfo.cs @@ -23,6 +23,7 @@ permissions and limitations under the Licenses. using MCGalaxy.Games; using MCGalaxy.Levels.IO; using MCGalaxy.Maths; +using MCGalaxy.Network; using BlockID = System.UInt16; namespace MCGalaxy.Commands.Info @@ -159,6 +160,9 @@ void ShowEnv(Player p, MapInfo data, LevelConfig cfg) { p.Message("Fancy colors: &eLavaLight {0}, &eLampLight {1}", Color(cfg.LavaLightColor), Color(cfg.LampLightColor)); } + if (cfg.LightingMode != Packet.LightingMode.None) { + p.Message("Lighting Mode: &b{0}{1}", cfg.LightingMode, cfg.LightingModeLocked ? "&c locked" : ""); + } p.Message("Water level: &b{0}&S, Bedrock offset: &b{1}&S, Clouds height: &b{2}&S, Max fog distance: &b{3}", data.Get(EnvProp.EdgeLevel), data.Get(EnvProp.SidesOffset), data.Get(EnvProp.CloudsLevel), data.Get(EnvProp.MaxFog)); diff --git a/MCGalaxy/Levels/LevelConfig.cs b/MCGalaxy/Levels/LevelConfig.cs index 0ed08ec03..92c9be0d9 100644 --- a/MCGalaxy/Levels/LevelConfig.cs +++ b/MCGalaxy/Levels/LevelConfig.cs @@ -21,6 +21,7 @@ permissions and limitations under the Licenses. using MCGalaxy.Config; using MCGalaxy.Games; using MCGalaxy.Modules.Games.ZS; +using MCGalaxy.Network; using BlockID = System.UInt16; namespace MCGalaxy @@ -137,6 +138,11 @@ public abstract class EnvConfig [ConfigString("LampLightColor", "Env", "", true)] public string LampLightColor = ""; + [ConfigEnum("LightingMode", "Env", Packet.LightingMode.None, typeof(Packet.LightingMode))] + public Packet.LightingMode LightingMode; + [ConfigBool("LightingModeLocked", "Env", false)] + public bool LightingModeLocked = false; + public void ResetEnv() { // TODO: Rewrite using ConfigElement somehow Weather = ENV_USE_DEFAULT; @@ -163,6 +169,9 @@ public void ResetEnv() { SkyboxColor = ""; LavaLightColor = ""; LampLightColor = ""; + + LightingMode = Packet.LightingMode.None; + LightingModeLocked = false; } internal const int ENV_COLOR_COUNT = 7; diff --git a/MCGalaxy/Levels/LevelEnv.cs b/MCGalaxy/Levels/LevelEnv.cs index 2352d75b1..f058b028d 100644 --- a/MCGalaxy/Levels/LevelEnv.cs +++ b/MCGalaxy/Levels/LevelEnv.cs @@ -18,6 +18,7 @@ permissions and limitations under the Licenses. using System; using System.Collections.Generic; using MCGalaxy.Commands; +using MCGalaxy.Network; using BlockID = System.UInt16; namespace MCGalaxy { @@ -50,6 +51,8 @@ public static class EnvOptions { new EnvOption("Skybox", SetSkybox, "&HSets color of the skybox (default FFFFFF)"), new EnvOption("LavaLight", SetLavaLight, "&HSets color cast by bright natural blocks when fancy lighting is enabled (default FFEBC6)"), new EnvOption("LampLight", SetLampLight, "&HSets color cast by bright artificial blocks when fancy lighting is enabled (default FFFFFF)"), + new EnvOption("LightingMode", SetLightingMode, "&HSets the lighting mode, which can be Classic or Fancy. " + + "Add \"locked\" on the end to lock the mode. For example: &Tlightingmode classic locked"), new EnvOption("CloudsSpeed", SetCloudsSpeed, "&HSets how fast clouds move (negative moves in opposite direction)"), new EnvOption("WeatherSpeed", SetWeatherSpeed, "&HSets how fast rain/snow falls (negative falls upwards)"), new EnvOption("WeatherFade", SetWeatherFade, "&HSets how quickly rain/snow fades out over distance"), @@ -75,6 +78,7 @@ public static EnvOption Find(string opt) { if (opt.CaselessEq("SkyboxVer")) opt = "SkyboxVerSpeed"; if (opt.CaselessEq("lavacolor")) opt = "LavaLight"; if (opt.CaselessEq("lampcolor")) opt = "LampLight"; + if (opt.CaselessEq("lighting")) opt = "LightingMode"; foreach (EnvOption option in Options) { if (option.Name.CaselessEq(opt)) return option; @@ -127,6 +131,16 @@ static void SetLavaLight(Player p, string area, EnvConfig cfg, string value) { static void SetLampLight(Player p, string area, EnvConfig cfg, string value) { SetColor(p, value, area, "block lamp light color", ref cfg.LampLightColor); } + static void SetLightingMode(Player p, string area, EnvConfig cfg, string value) { + string[] args = value.SplitSpaces(2); + string lightingMode = args[0]; + bool locked = args.Length > 1 && args[1].CaselessEq("locked"); + + if (!SetEnum(p, lightingMode, area, "lighting mode", Packet.LightingMode.None, ref cfg.LightingMode)) return; + cfg.LightingModeLocked = locked; + if (locked) p.Message("Lighting mode for {0}&S was %clocked%S. Players will not be able to change lighting mode while inside.", area); + if (!p.Supports(CpeExt.LightingMode)) p.Message("&WNote: Your client does not support lighting modes, so you will see no changes."); + } static void SetCloudsSpeed(Player p, string area, EnvConfig cfg, string value) { SetFloat(p, value, area, 256, "clouds speed", ref cfg.CloudsSpeed, -0xFFFFFF, 0xFFFFFF); @@ -240,5 +254,17 @@ static void SetColor(Player p, string input, string area, string variable, ref s target = Utils.Hex(rgb.R, rgb.G, rgb.B); } } + + static bool SetEnum(Player p, string input, string area, string variable, T resetValue, ref T target) where T : struct { + if (IsResetString(input)) { + p.Message("Reset {0} for {1} &Sto normal", variable, area); + target = resetValue; + return true; + } else { + if (!CommandParser.GetEnum(p, input, variable, ref target)) return false; + p.Message("Set {0} for {1} &Sto {2}", variable, area, target.ToString()); + return true; + } + } } } \ No newline at end of file diff --git a/MCGalaxy/Network/CPESupport.cs b/MCGalaxy/Network/CPESupport.cs index 494856034..71da3dcaa 100644 --- a/MCGalaxy/Network/CPESupport.cs +++ b/MCGalaxy/Network/CPESupport.cs @@ -92,6 +92,7 @@ public class CpeExt public const string CustomModels = "CustomModels"; public const string PluginMessages = "PluginMessages"; public const string ExtEntityTeleport = "ExtEntityTeleport"; + public const string LightingMode = "LightingMode"; } public sealed class CpeExtension @@ -151,6 +152,7 @@ public CpeExtension(string name, string desc, byte version) { new CpeExtension(CpeExt.CustomModels, "Allows defining custom models for entities", 2), new CpeExtension(CpeExt.PluginMessages, "Allows sending and receiving plugin messages from clients"), new CpeExtension(CpeExt.ExtEntityTeleport, "Allows sending more precisely controlled teleports"), + new CpeExtension(CpeExt.LightingMode, "Allows changing how the client lights worlds"), #if TEN_BIT_BLOCKS new CpeExtension(CpeExt.ExtBlocks, "Allows using block IDs over 255 in block definitions"), #endif diff --git a/MCGalaxy/Network/Packets/Opcode.cs b/MCGalaxy/Network/Packets/Opcode.cs index 4a695690e..7887a6227 100644 --- a/MCGalaxy/Network/Packets/Opcode.cs +++ b/MCGalaxy/Network/Packets/Opcode.cs @@ -78,5 +78,6 @@ public static class Opcode { public const byte CpeUndefineModel = 52; public const byte CpePluginMessage = 53; public const byte CpeEntityTeleportExt = 54; + public const byte CpeLightingMode = 55; } } diff --git a/MCGalaxy/Network/Packets/Packet.cs b/MCGalaxy/Network/Packets/Packet.cs index 5d05ced05..2b1e6d440 100644 --- a/MCGalaxy/Network/Packets/Packet.cs +++ b/MCGalaxy/Network/Packets/Packet.cs @@ -681,6 +681,15 @@ public static byte[] TeleportExt(byte entityID, bool usePos, TeleportMoveMode mo buffer[4 + offset] = rot.HeadX; return buffer; } + + public enum LightingMode { None, Classic, Fancy } + public static byte[] SetLightingMode(LightingMode mode, bool locked) { + byte[] buffer = new byte[3]; + buffer[0] = Opcode.CpeLightingMode; + buffer[1] = (byte)mode; + buffer[2] = (byte)(locked ? 1 : 0); + return buffer; + } #endregion diff --git a/MCGalaxy/Player/Player.Handlers.cs b/MCGalaxy/Player/Player.Handlers.cs index 15c647710..cb3e8c1c4 100644 --- a/MCGalaxy/Player/Player.Handlers.cs +++ b/MCGalaxy/Player/Player.Handlers.cs @@ -316,6 +316,21 @@ public void SendCurrentEnv() { Send(Packet.EnvMapProperty(i, value)); } } + if (Supports(CpeExt.LightingMode)) { + EnvConfig cfg; + if (zone != null && zone.Config.LightingMode != Packet.LightingMode.None) { + // Zone takes most precedence if it has a setting + cfg = zone.Config; + } else { + if (level.Config.LightingMode == Packet.LightingMode.None) { + // If level has no setting, use global + cfg = Server.Config; + } else { + cfg = level.Config; + } + } + Send(Packet.SetLightingMode(cfg.LightingMode, cfg.LightingModeLocked)); + } int weather = CurrentEnvProp(EnvProp.Weather, zone); Session.SendSetWeather((byte)weather);