Example #1
0
 public static bool PackLuaTable(IList target, out LuaTable result)
 {
     Type[] genericArguments = target.GetType().GetGenericArguments();
     result = new LuaTable();
     try
     {
         for (int i = 0; i < target.Count; i++)
         {
             if (IsBaseType(genericArguments[0]))
             {
                 if (genericArguments[0] == typeof(bool))
                 {
                     result.Add((int)(i + 1), ((bool)target[i]) ? 1 : 0);
                 }
                 else
                 {
                     result.Add((int)(i + 1), target[i]);
                 }
             }
             else
             {
                 LuaTable table;
                 if (PackLuaTable(target[i], out table))
                 {
                     result.Add((int)(i + 1), table);
                 }
             }
         }
     }
     catch (Exception exception)
     {
         LoggerHelper.Error("PackLuaTable list error: " + exception.Message, true);
     }
     return(true);
 }
Example #2
0
        /// <summary>
        /// 转换复杂类型的对象到LuaTable,不支持基础类型直接转换。
        /// </summary>
        /// <param name="target"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static bool PackLuaTable(object target, out LuaTable result)
        {
            var type = target.GetType();

            if (type == typeof(LuaTable))
            {
                result = target as LuaTable;
                return(true);
            }
            if (type.IsGenericType)
            {//容器类型
                //目前只支持列表与字典的容器类型转换
                if (type.GetGenericTypeDefinition() == typeof(Dictionary <,>))
                {
                    return(PackLuaTable(target as IDictionary, out result));
                }
                else
                {
                    return(PackLuaTable(target as IList, out result));
                }
            }
            else
            {//实体类型
                result = new LuaTable();
                try
                {
                    var props = type.GetProperties(~BindingFlags.Static);
                    for (int i = 0; i < props.Length; i++)
                    {
                        var prop = props[i];
                        if (IsBaseType(prop.PropertyType))
                        {
                            result.Add(i + 1, prop.GetGetMethod().Invoke(target, null));
                        }
                        else
                        {
                            LuaTable lt;
                            var      value = prop.GetGetMethod().Invoke(target, null);
                            var      flag  = PackLuaTable(value, out lt);
                            if (flag)
                            {
                                result.Add(i + 1, lt);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    LoggerHelper.Error("PackLuaTable entity error: " + ex.Message);
                }
            }
            return(true);
        }
Example #3
0
        /// <summary>
        /// 转换字典类型的对象到LuaTable。
        /// </summary>
        /// <param name="target"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static bool PackLuaTable(IDictionary target, out LuaTable result)
        {
            Type[] types = target.GetType().GetGenericArguments();
            result = new LuaTable();
            try
            {
                foreach (DictionaryEntry item in target)
                {
                    if (IsBaseType(types[1]))
                    {
                        object value;
                        if (types[1] == typeof(bool))//判断值是否布尔类型,是则做特殊转换
                        {
                            value = (bool)item.Value ? 1 : 0;
                        }
                        else
                        {
                            value = item.Value;
                        }

                        if (types[0] == typeof(int))//判断键是否为整型,是则标记键为整型,转lua table字符串时有用
                        {
                            result.Add(item.Key.ToString(), false, value);
                        }
                        else
                        {
                            result.Add(item.Key.ToString(), value);
                        }
                    }
                    else
                    {
                        LuaTable value;
                        var      flag = PackLuaTable(item.Value, out value);
                        if (flag)
                        {
                            if (types[0] == typeof(int))
                            {
                                result.Add(item.Key.ToString(), false, value);
                            }
                            else
                            {
                                result.Add(item.Key.ToString(), value);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LoggerHelper.Error("PackLuaTable dictionary error: " + ex.Message);
            }
            return(true);
        }
Example #4
0
 public static bool PackLuaTable(IDictionary target, out LuaTable result)
 {
     Type[] genericArguments = target.GetType().GetGenericArguments();
     result = new LuaTable();
     try
     {
         foreach (DictionaryEntry entry in target)
         {
             if (IsBaseType(genericArguments[1]))
             {
                 object obj2;
                 if (genericArguments[1] == typeof(bool))
                 {
                     obj2 = ((bool)entry.Value) ? 1 : 0;
                 }
                 else
                 {
                     obj2 = entry.Value;
                 }
                 if (genericArguments[0] == typeof(int))
                 {
                     result.Add(entry.Key.ToString(), false, obj2);
                 }
                 else
                 {
                     result.Add(entry.Key.ToString(), obj2);
                 }
             }
             else
             {
                 LuaTable table;
                 if (PackLuaTable(entry.Value, out table))
                 {
                     if (genericArguments[0] == typeof(int))
                     {
                         result.Add(entry.Key.ToString(), false, table);
                     }
                     else
                     {
                         result.Add(entry.Key.ToString(), table);
                     }
                 }
             }
         }
     }
     catch (Exception exception)
     {
         LoggerHelper.Error("PackLuaTable dictionary error: " + exception.Message, true);
     }
     return(true);
 }
        protected void SendClientMissionMessage()
        {
            // 真正向服务器发, to do
            LuaTable result = new LuaTable();

            LuaTable temp;

            Mogo.RPC.Utils.PackLuaTable(localAvatarCollectedDrops, out temp);
            result.Add(1, temp);
            result.Add(2, localAvatarCollectedMoney);
            result.Add(3, localAvatarCollectedExp);

            MogoWorld.thePlayer.RpcCall("MissionExReq", (byte)MissionHandleCode.UPLOAD_COMBO_AND_BOTTLE, (ushort)localAvatarCombo, (ushort)localAvatarBottle, (ushort)(localServerAvatar.defaultReviveTimes - localServerAvatar.reviveTimes), Mogo.RPC.Utils.PackLuaTable(result));
        }
Example #6
0
            public LuaTable ToLuaTable()
            {
                dynamic table = new LuaTable();

                table.shaderPath            = shaderPath;
                table.outputDirectory       = outputDirectory;
                table.intermediateDirectory = intermediateDirectory;

                table.entryPoint   = entryPoint;
                table.optimization = optimization;
                table.profile      = profile;
                table.debug        = debug;
                table.outputFile   = outputFile;

                LuaTable definesTable = new LuaTable();

                for (int i = 0; i < defines.Length; i++)
                {
                    definesTable.Add(defines[i]);
                }

                table.defines = definesTable;

                return(table);
            }
Example #7
0
 private static void EncounteredString(LuaTable currentTable, string currentIdentifier, string val)
 {
     if (currentIdentifier == null)
     {
         currentIdentifier = currentTable.Count.ToString();
     }
     currentTable.Add(currentIdentifier, new LuaValue(val));
 }
Example #8
0
        public static bool MsgUnPackTable(out LuaTable luatable, ref MessagePackObject pObj)
        {
            LuaTable result = new LuaTable();

            luatable = result;
            var    mPk      = pObj.AsDictionary();
            bool   isString = false;
            string key;
            object value;

            foreach (var item in mPk)
            {
                //parse for key
                MessagePackObject mKey = item.Key;
                if (mKey.IsRaw)
                {
                    key      = mKey.AsString();
                    isString = true;
                }
                else if (true == mKey.IsTypeOf <double>())
                {
                    key = mKey.AsDouble().ToString();
                }
                else
                {
                    LoggerHelper.Error("key type error");
                    return(false);
                }
                //parse for value
                MessagePackObject mValue = item.Value;
                if (mValue.IsRaw)
                {
                    value = mValue.AsString();
                }
                else if (mValue.IsDictionary)
                {
                    LuaTable luatbl;
                    MsgUnPackTable(out luatbl, ref mValue);
                    value = luatbl;
                }
                else if (true == mValue.IsTypeOf <bool>())
                {
                    value = mValue.AsBoolean();
                }
                else if (true == mValue.IsTypeOf <double>())
                {
                    value = mValue.AsDouble();
                }
                else
                {
                    LoggerHelper.Error("value type error");
                    return(false);
                }
                result.Add(key, isString, value);
                isString = false;
            }
            return(true);
        }
Example #9
0
        }         // func GetRowData

        private static LuaTable AddColumnInfo(IReadOnlyList <IDataColumn> columns, LuaTable columnList)
        {
            foreach (var c in columns)
            {
                columnList.Add(GetColumnData(c, new LuaTable()));
            }

            return(columnList);
        }         // proc AddColumnInfo
Example #10
0
        public static bool PackLuaTable(object target, out LuaTable result)
        {
            Type type = target.GetType();

            if (type == typeof(LuaTable))
            {
                result = target as LuaTable;
                return(true);
            }
            if (type.IsGenericType)
            {
                if (type.GetGenericTypeDefinition() == typeof(Dictionary <,>))
                {
                    return(PackLuaTable(target as IDictionary, out result));
                }
                return(PackLuaTable(target as IList, out result));
            }
            result = new LuaTable();
            try
            {
                PropertyInfo[] properties = type.GetProperties(~BindingFlags.Static);
                for (int i = 0; i < properties.Length; i++)
                {
                    PropertyInfo info = properties[i];
                    if (IsBaseType(info.PropertyType))
                    {
                        result.Add((int)(i + 1), info.GetGetMethod().Invoke(target, null));
                    }
                    else
                    {
                        LuaTable table;
                        if (PackLuaTable(info.GetGetMethod().Invoke(target, null), out table))
                        {
                            result.Add((int)(i + 1), table);
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                LoggerHelper.Error("PackLuaTable entity error: " + exception.Message, true);
            }
            return(true);
        }
Example #11
0
        public static bool MsgUnPackTable(out LuaTable luatable, ref MessagePackObject pObj)
        {
            LuaTable table = new LuaTable();

            luatable = table;
            MessagePackObjectDictionary dictionary = pObj.AsDictionary();
            bool isString = false;

            foreach (KeyValuePair <MessagePackObject, MessagePackObject> pair in dictionary)
            {
                string            str;
                object            obj2;
                MessagePackObject key = pair.Key;
                if (key.IsRaw)
                {
                    str      = key.AsString();
                    isString = true;
                }
                else if (key.IsTypeOf <double>() == true)
                {
                    str = key.AsDouble().ToString();
                }
                else
                {
                    LoggerHelper.Error("key type error", true);
                    return(false);
                }
                MessagePackObject obj4 = pair.Value;
                if (obj4.IsRaw)
                {
                    obj2 = obj4.AsString();
                }
                else if (obj4.IsDictionary)
                {
                    LuaTable table2;
                    MsgUnPackTable(out table2, ref obj4);
                    obj2 = table2;
                }
                else if (obj4.IsTypeOf <bool>() == true)
                {
                    obj2 = obj4.AsBoolean();
                }
                else if (obj4.IsTypeOf <double>() == true)
                {
                    obj2 = obj4.AsDouble();
                }
                else
                {
                    LoggerHelper.Error("value type error", true);
                    return(false);
                }
                table.Add(str, isString, obj2);
                isString = false;
            }
            return(true);
        }
Example #12
0
        private LuaTable CreateTypeListTable(IEnumerable <MoaiClass> classes)
        {
            var typeListTable = new LuaTable();

            foreach (MoaiClass moaiClass in classes.OrderBy(c => c.Name))
            {
                typeListTable.Add(moaiClass.Name, CreateTypeTable(moaiClass));
            }
            return(typeListTable);
        }
Example #13
0
        }         // proc CloseCursorAsync

        private async Task GetDataSetAsync(LuaTable table)
        {
            var identification = table.GetMemberValue("id") ?? throw new ArgumentNullException("id");
            var tableFilter    = GetStringArray(table, "filter");

            var dataset = await provider.GetDataSetAsync(identification, tableFilter);

            var result = new LuaTable();

            foreach (var tab in dataset.Tables)
            {
                if (tableFilter.Length != 0 &&
                    Array.Exists(tableFilter, c => String.Compare(c, tab.TableName, StringComparison.OrdinalIgnoreCase) != 0))
                {
                    continue;
                }

                var resultTable = new LuaTable();

                var columnList = new LuaTable();
                foreach (var col in tab.Columns)
                {
                    var resultColumn = GetColumnData(col, new LuaTable());

                    if (col.IsRelationColumn)
                    {
                        resultColumn["parentReleation"] = new LuaTable()
                        {
                            ["table"]  = col.ParentColumn.ParentColumn.Table.Name,
                            ["column"] = col.ParentColumn.ParentColumn.Name
                        };
                    }

                    columnList.Add(resultColumn);
                }

                resultTable["columns"] = columnList;

                // convert rows
                foreach (var row in tab)
                {
                    resultTable.Add(GetRowData(new LuaTable(), row));
                }

                result[tab.TableName] = resultTable;
            }

            await PushPacketAsync(result);
        }         // proc ExecuteAsync
Example #14
0
 /// <summary>
 /// 转换列表类型的对象到LuaTable。
 /// </summary>
 /// <param name="target"></param>
 /// <param name="result"></param>
 /// <returns></returns>
 public static bool PackLuaTable(IList target, out LuaTable result)
 {
     Type[] types = target.GetType().GetGenericArguments();
     result = new LuaTable();
     try
     {
         for (int i = 0; i < target.Count; i++)
         {
             if (IsBaseType(types[0]))
             {
                 if (types[0] == typeof(bool))
                 {
                     result.Add(i + 1, (bool)target[i] ? 1 : 0);
                 }
                 else
                 {
                     result.Add(i + 1, target[i]);
                 }
             }
             else
             {
                 LuaTable value;
                 var      flag = PackLuaTable(target[i], out value);
                 if (flag)
                 {
                     result.Add(i + 1, value);
                 }
             }
         }
     }
     catch (Exception ex)
     {
         LoggerHelper.Error("PackLuaTable list error: " + ex.Message);
     }
     return(true);
 }
Example #15
0
        private LuaTable CreateMemberListTable(MoaiClass moaiClass)
        {
            var memberListTable = new LuaTable();

            IEnumerable <ClassMember> directMembers = moaiClass.Members
                                                      .OrderBy(member => member.GetType().Name) // Attribute, then Constant, Flag, Method
                                                      .ThenBy(member => member.Name);

            foreach (var member in directMembers)
            {
                memberListTable.Add(member.Name, CreateMemberTable((dynamic)member));
            }

            return(memberListTable);
        }
Example #16
0
    /// <summary>
    ///
    /// </summary>
    /// <param name="playerId">玩家id</param>
    /// <param name="startStarId">出发星球</param>
    /// <param name="endStarId">目标星球</param>
    /// <param name="isSelfProduce">1表示只出战自产兵,0表示全部出战</param>
    /// <param name="soldierTypeList">出战兵种id列表</param>
    /// <param name="percent">出战各兵种统一数量百分比,0表示只出战一个</param>
    /// <returns></returns>
    public LuaTable MoveSoldierToLuaTable(uint playerId, int startStarId, int endStarId, int isSelfProduce, float _soldierNumPercent, List <int> fightSoldierIdList)
    {
        LuaTable lt = new LuaTable();

        lt.Add(0, playerId);
        lt.Add(1, startStarId);
        lt.Add(2, endStarId);
        lt.Add(3, isSelfProduce);

        LuaTable soldierTypeLuaTable = new LuaTable();

        for (int i = 0; i < fightSoldierIdList.Count; i++)
        {
            soldierTypeLuaTable.Add(i, fightSoldierIdList[i]);
        }

        lt.Add(4, soldierTypeLuaTable);
        lt.Add(5, 1 - _soldierNumPercent);
        return(lt);
    }
Example #17
0
        private static bool DecodeLuaTable(byte[] inputString, int len, ref int index, out object result)
        {
            var luaTable = new LuaTable();

            result = luaTable;
            if (!Utils.WaitChar(inputString, '{', ref index))
            {
                return(false);
            }
            try
            {
                if (Utils.WaitChar(inputString, '}', ref index)) //如果下一个字符为右大括号表示为空Lua table
                {
                    return(true);
                }
                while (index < len)
                {
                    string key;
                    bool   isString;
                    object value;
                    Utils.DecodeKey(inputString, ref index, out key, out isString); //匹配键
                    Utils.WaitChar(inputString, '=', ref index);                    //匹配键值对分隔符
                    var flag = DecodeLuaValue(inputString, ref index, out value);   //转换实体
                    if (flag)
                    {
                        luaTable.Add(key, isString, value);
                    }
                    if (!Utils.WaitChar(inputString, ',', ref index))
                    {
                        break;
                    }
                }
                Utils.WaitChar(inputString, '}', ref index);
                return(true);
            }
            catch (Exception e)
            {
                LoggerHelper.Error("Parse LuaTable error: " + inputString + e);
                return(false);
            }
        }
Example #18
0
        }         // proc NextCursorAsync

        private async Task NextCursorCountAsync(LuaTable table)
        {
            // get parameter
            var cursor = GetCursor(table);
            var count  = Procs.ChangeType <int>(table.GetMemberValue("count") ?? -1);

            // collect rows
            var rows = new LuaTable();

            while (count-- > 0 && cursor.MoveNext())
            {
                rows.Add(cursor.GetCurrentRow());
            }

            // send result
            await PushPacketAsync(new LuaTable()
            {
                ["id"]  = cursor.Id,
                ["row"] = rows.Length == 0 ? null : rows
            });
        }         // proc NextCursorCountAsync
Example #19
0
        private static bool DecodeLuaTable(string inputString, ref int index, out object result)
        {
            LuaTable table = new LuaTable();

            result = table;
            if (!WaitChar(inputString, '{', ref index))
            {
                return(false);
            }
            try
            {
                if (!WaitChar(inputString, '}', ref index))
                {
                    while (index < inputString.Length)
                    {
                        string str;
                        bool   flag;
                        object obj2;
                        DecodeKey(inputString, ref index, out str, out flag);
                        WaitChar(inputString, '=', ref index);
                        if (DecodeLuaValue(inputString, ref index, out obj2))
                        {
                            table.Add(str, flag, obj2);
                        }
                        if (!WaitChar(inputString, ',', ref index))
                        {
                            break;
                        }
                    }
                    WaitChar(inputString, '}', ref index);
                }
                return(true);
            }
            catch (Exception exception)
            {
                LoggerHelper.Error("Parse LuaTable error: " + inputString + exception.ToString(), true);
                return(false);
            }
        }
        protected void LoadLuaContext(string pathToMainFile, bool loadChildrenLuaLinks, bool specificChildrenOnly, IReadOnlyCollection <string> specificChildrenKeys)
        {
            var originalDirectory = Directory.GetCurrentDirectory();

            Directory.SetCurrentDirectory(_pathToConfigFolder);

            bool success = true;

            try
            {
                using (var lua = new Lua())
                {
                    dynamic g = lua.CreateEnvironment <LuaGlobal>();

                    // add in optional helper methods etc.
                    ExtendLuaEnvironment(g);

                    int baseMemberCount = ((LuaGlobal)g).Members.Count;

                    AddUserDefinedGlobals(g);

                    // each found type has its instance created in lua context as a table - this populates the tables with default values, if any are set
                    foreach (var typeAttributePair in _typesWithAttributes)
                    {
                        var type             = typeAttributePair.Key;
                        var instance         = Activator.CreateInstance(type);
                        var attribute        = typeAttributePair.Value;
                        var keyFromAttribute = attribute.Key;

                        var json  = JsonConvert.SerializeObject(instance);
                        var table = LuaTable.FromJson(json);

                        g[keyFromAttribute] = table;
                        _settingsInstances.Add(keyFromAttribute, instance);
                    }

                    LuaChunk chunk;
                    // compile the lua chunk
                    try
                    {
                        chunk = lua.CompileChunk(_mainSettingsFileName, new LuaCompileOptions()
                        {
                            DebugEngine = new LuaDebugger()
                        });
                    }
                    catch (LuaParseException e)
                    {
                        success = false;
                        Console.WriteLine($"Exception caught when parsing the lua file at line {e.Line}, column {e.Column}, source file {e.FileName}. Exception: {e}");
                        Console.WriteLine($"Offending line: {TryToGetExceptionLineFromFile(e)}");
                        throw;
                    }

                    try
                    {
                        // actually run the chunk
                        g.dochunk(chunk);

                        // lua tables can contain 'links' to other lua scripts - user can specify if they want to find those files and run those chunks as well
                        if (loadChildrenLuaLinks)
                        {
                            var globals      = ((LuaGlobal)g).Members;
                            var addedGlobals = globals.Skip(baseMemberCount).ToList();
                            var global       = g as LuaGlobal;
                            foreach (var member in addedGlobals)
                            {
                                var table = member.Value as LuaTable;
                                if (table == null)
                                {
                                    continue;
                                }

                                if (specificChildrenOnly && specificChildrenKeys.Contains(member.Key))
                                {
                                    RunChildLuaScripts(lua, ref global, table);
                                }
                                else if (!specificChildrenOnly)
                                {
                                    RunChildLuaScripts(lua, ref global, table);
                                }
                            }
                        }
                    }
                    catch (LuaParseException e)
                    {
                        success = false;
                        Console.WriteLine($"Could not parse lua exception: {e}. File {e.FileName}, Line {e.Line}, Index {e.Index}.");
                    }
                    catch (Exception e)
                    {
                        success = false;
                        Console.WriteLine($"Exception {e}");
                        // get stack trace if possible
                        var d = LuaExceptionData.GetData(e);
                        Console.WriteLine($"StackTrace: {d.FormatStackTrace(0, false)}");
                        throw;
                    }

                    // getting actual C# object representations back from the lua tables
                    var count = _settingsInstances.Count;
                    for (int index = 0; index < count; index++)
                    {
                        var instancePair = _settingsInstances.ElementAt(index);

                        // key under which the settings section has been registered
                        var key = instancePair.Key;
                        // the table filled with data from lua
                        var dynamicTable = g[key];
                        // the type of the C# object representing the settings section (needed for deserialization)
                        var typeToCreate = _typesWithAttributes.FirstOrDefault(p => p.Value.Key == key).Key;
                        // convert table to json
                        string instanceAsJson = LuaTable.ToJson(dynamicTable);
                        // deserialize json to our type
                        //var deserializedInstance = JsonSerializer.Deserialize(instanceAsJson, typeToCreate);
                        var deserializedInstance = JsonConvert.DeserializeObject(instanceAsJson, typeToCreate);
                        // store this instance
                        _settingsInstances[key] = deserializedInstance;
                    }

                    var members = ((LuaGlobal)g).Members;
                    //var relevantMembers = members.Skip(baseMemberCount).ToList();
                    var relevantMembers = members.Skip(baseMemberCount).ToDictionary(kv => kv.Key, kv => kv.Value);

                    // cache the results in tables
                    _tableCache = new LuaTable();

                    // skip methods defined in lua from caching - two reasons for that:
                    // 1) Json generation explodes on delegates,
                    // 2) they would most likely not be safe to call after the lua context is disposed anyway
                    var scrubbed = ScrubDelegateMembersFromTable(relevantMembers);
                    foreach (var pair in scrubbed)
                    {
                        _tableCache.Add(pair.Key, pair.Value);
                    }


                    var jsonCache = _tableCache.ToJson();
                    _jsonCache = JObject.Parse(jsonCache);
                }
            }
            finally
            {
                Directory.SetCurrentDirectory(originalDirectory);
                Console.WriteLine(success ? "Settings loaded successfully" : "Problem occurred when loading settings");
            }
        }
Example #21
0
 private LuaTable CreateTypeListTable(IEnumerable<MoaiType> types)
 {
     var typeListTable = new LuaTable();
     foreach (MoaiType type in types.OrderBy(t => t.Name)) {
         typeListTable.Add(new LuaComment(type.Signature, blankLineBefore: typeListTable.Any()));
         typeListTable.Add(type.Name, CreateTypeTable(type));
     }
     return typeListTable;
 }
Example #22
0
        private LuaTable CreateMemberListTable(MoaiType type)
        {
            var memberListTable = new LuaTable();

            memberListTable.Add(new LuaComment("Direct members"));
            IEnumerable<MoaiTypeMember> directMembers = type.Members
                .OrderBy(member => member.GetType().Name) // MoaiAttribute, then MoaiConstant, MoaiFlag, MoaiMethod
                .ThenBy(member => member.Name);
            foreach (var member in directMembers) {
                memberListTable.Add(member.Name, CreateMemberTable((dynamic) member));
            }

            if (type.InheritedMembers.Any()) {
                memberListTable.Add(new LuaComment("Inherited members", blankLineBefore: true));
                var inheritedMembers = type.InheritedMembers
                    .OrderBy(member => member.GetType().Name)
                    .ThenBy(member => member.Name);
                foreach (var member in inheritedMembers) {
                    memberListTable.Add(member.Name, CreateMemberTable((dynamic) member));
                }
            }

            return memberListTable;
        }
Example #23
0
 private static bool DecodeLuaTable(byte[] inputString, ref int index, out object result)
 {
     var luaTable = new LuaTable();
     result = luaTable;
     if (!WaitChar(inputString, '{', ref index))
     {
         return false;
     }
     try
     {
         if (WaitChar(inputString, '}', ref index))//如果下一个字符为右大括号表示为空Lua table
             return true;
         while (index < inputString.Length)
         {
             string key;
             bool isString;
             object value;
             DecodeKey(inputString, ref index, out key, out isString);//匹配键
             WaitChar(inputString, '=', ref index);//匹配键值对分隔符
             var flag = DecodeLuaValue(inputString, ref index, out value);//转换实体
             if (flag)
             {
                 luaTable.Add(key, isString, value);
             }
             if (!WaitChar(inputString, ',', ref index))
                 break;
         }
         WaitChar(inputString, '}', ref index);
         return true;
         
     }
     catch (Exception e)
     {
         LoggerHelper.Error("Parse LuaTable error: " + inputString + e.ToString());
         return false;
     }
 }
Example #24
0
        /// <summary>
        /// 转换字典类型的对象到LuaTable。
        /// </summary>
        /// <param name="target"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static bool PackLuaTable(IDictionary target, out LuaTable result)
        {
            Type[] types = target.GetType().GetGenericArguments();
            result = new LuaTable();
            try
            {
                foreach (DictionaryEntry item in target)
                {
                    if (IsBaseType(types[1]))
                    {
                        object value;
                        if (types[1] == typeof(bool))//判断值是否布尔类型,是则做特殊转换
                            value = (bool)item.Value ? 1 : 0;
                        else
                            value = item.Value;

                        if (types[0] == typeof(int))//判断键是否为整型,是则标记键为整型,转lua table字符串时有用
                            result.Add(item.Key.ToString(), false, value);
                        else
                            result.Add(item.Key.ToString(), value);
                    }
                    else
                    {
                        LuaTable value;
                        var flag = PackLuaTable(item.Value, out value);
                        if (flag)
                        {
                            if (types[0] == typeof(int))
                                result.Add(item.Key.ToString(), false, value);
                            else
                                result.Add(item.Key.ToString(), value);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LoggerHelper.Error("PackLuaTable dictionary error: " + ex.Message);
            }
            return true;
        }
Example #25
0
 /// <summary>
 /// 转换列表类型的对象到LuaTable。
 /// </summary>
 /// <param name="target"></param>
 /// <param name="result"></param>
 /// <returns></returns>
 public static bool PackLuaTable(IList target, out LuaTable result)
 {
     Type[] types = target.GetType().GetGenericArguments();
     result = new LuaTable();
     try
     {
         for (int i = 0; i < target.Count; i++)
         {
             if (IsBaseType(types[0]))
             {
                 if (types[0] == typeof(bool))
                     result.Add(i + 1, (bool)target[i] ? 1 : 0);
                 else
                     result.Add(i + 1, target[i]);
             }
             else
             {
                 LuaTable value;
                 var flag = PackLuaTable(target[i], out value);
                 if (flag)
                     result.Add(i + 1, value);
             }
         }
     }
     catch (Exception ex)
     {
         LoggerHelper.Error("PackLuaTable list error: " + ex.Message);
     }
     return true;
 }
Example #26
0
        /// <summary>
        ///     Sets up all the things that Springie needs to know for the battle: how to balance, who to get extra commanders,
        ///     what PlanetWars structures to create, etc.
        /// </summary>
        public static LobbyHostingContext GetDedicatedServerStartSetup(LobbyHostingContext context)
        {
            var ret = context;

            try
            {
                var mode = context.Mode;

                var commProfiles = new LuaTable();
                var db           = new ZkDataContext();

                // calculate to whom to send extra comms
                var accountIDsWithExtraComms = new List <int>();
                if (mode == AutohostMode.Planetwars || mode == AutohostMode.GameFFA || mode == AutohostMode.Teams)
                {
                    var groupedByTeam = context.Players.Where(x => !x.IsSpectator).GroupBy(x => x.AllyID).OrderByDescending(x => x.Count());
                    var biggest       = groupedByTeam.FirstOrDefault();
                    if (biggest != null)
                    {
                        foreach (var other in groupedByTeam.Skip(1))
                        {
                            var cnt = biggest.Count() - other.Count();
                            if (cnt > 0)
                            {
                                foreach (var a in
                                         other.Select(x => db.Accounts.First(y => y.AccountID == x.LobbyID))
                                         .OrderByDescending(x => x.GetRating(RatingCategory.Casual).Elo)
                                         .Take(cnt))
                                {
                                    accountIDsWithExtraComms.Add(a.AccountID);
                                }
                            }
                        }
                    }
                }


                // write Planetwars details to modoptions (for widget)
                Faction attacker = null;
                Faction defender = null;
                Planet  planet   = null;
                if (mode == AutohostMode.Planetwars)
                {
                    planet   = db.Galaxies.First(x => x.IsDefault).Planets.First(x => x.Resource.InternalName == context.Map);
                    attacker =
                        context.Players.Where(x => x.AllyID == 0 && !x.IsSpectator)
                        .Select(x => db.Accounts.First(y => y.AccountID == x.LobbyID))
                        .Where(x => x.Faction != null)
                        .Select(x => x.Faction)
                        .First();

                    defender = planet.Faction;

                    if (attacker == defender)
                    {
                        defender = null;
                    }

                    ret.ModOptions["attackingFaction"]      = attacker.Shortcut;
                    ret.ModOptions["attackingFactionName"]  = attacker.Name;
                    ret.ModOptions["attackingFactionColor"] = attacker.Color;
                    if (defender != null)
                    {
                        ret.ModOptions["defendingFaction"]      = defender.Shortcut;
                        ret.ModOptions["defendingFactionName"]  = defender.Name;
                        ret.ModOptions["defendingFactionColor"] = defender.Color;
                    }
                    else
                    {
                        ret.ModOptions["defendingFaction"]      = "Mercenary";
                        ret.ModOptions["defendingFactionName"]  = "Local militia";
                        ret.ModOptions["defendingFactionColor"] = "#CCCCCC";
                    }
                    ret.ModOptions["planet"] = planet.Name;
                }

                // write player custom keys (level, elo, is muted, etc.)
                foreach (var p in context.Players)
                {
                    var user = db.Accounts.Where(x => x.AccountID == p.LobbyID).Include(x => x.RelalationsByOwner).FirstOrDefault();
                    if (user != null)
                    {
                        var userParams = new Dictionary <string, string>();
                        ret.UserParameters[p.Name] = userParams;

                        userParams["LobbyID"]     = user.AccountID.ToString();
                        userParams["CountryCode"] = user.HideCountry ? "??" : user.Country;

                        var userBanMuted = Punishment.GetActivePunishment(user.AccountID, null, null, x => x.BanMute) != null;
                        if (userBanMuted)
                        {
                            userParams["muted"] = "1";
                        }
                        userParams["faction"]  = user.Faction != null ? user.Faction.Shortcut : "";
                        userParams["clan"]     = user.Clan != null ? user.Clan.Shortcut : "";
                        userParams["clanfull"] = user.Clan != null ? user.Clan.ClanName : "";

                        userParams["level"] = user.Level.ToString();
                        //userParams["mm_elo"] = Math.Round(user.EffectiveMmElo).ToString();
                        //userParams["casual_elo"] = Math.Round(user.EffectiveElo).ToString();

                        userParams["elo"] = Math.Round(user.GetBestRating().Elo).ToString();

                        userParams["icon"]      = user.GetIconName();
                        userParams["avatar"]    = user.Avatar;
                        userParams["badges"]    = string.Join(",", user.GetBadges());
                        userParams["admin"]     = user.AdminLevel >= AdminLevel.Moderator ? "1" : "0";
                        userParams["room_boss"] = p.Name == context.FounderName ? "1" : "0";
                        if (p.PartyID.HasValue)
                        {
                            userParams["PartyID"] = p.PartyID.ToString();
                        }

                        var userSpecChatBlocked = Punishment.GetActivePunishment(user.AccountID, null, null, x => x.BanSpecChat) != null;;
                        userParams["can_spec_chat"] = userSpecChatBlocked ? "0" : "1";

                        userParams["ignored"] = string.Join(",", user.RelalationsByOwner.Where(x => x.Relation == Relation.Ignore).Select(x => x.Target.Name));
                        userParams["friends"] = string.Join(",", user.RelalationsByOwner.Where(x => x.Relation == Relation.Friend).Select(x => x.Target.Name));

                        if (!p.IsSpectator)
                        {
                            // set valid PW structure attackers
                            if (mode == AutohostMode.Planetwars)
                            {
                                userParams["pwRank"] = (user.AccountRolesByAccountID.Where(
                                                            x =>
                                                            !x.RoleType.IsClanOnly &&
                                                            (x.RoleType.RestrictFactionID == null || x.RoleType.RestrictFactionID == user.FactionID)).OrderBy(x => x.RoleType.DisplayOrder).Select(x => (int?)x.RoleType.DisplayOrder).FirstOrDefault() ?? 999).ToString();


                                var allied = user.Faction != null && defender != null && user.Faction != defender &&
                                             defender.HasTreatyRight(user.Faction, x => x.EffectPreventIngamePwStructureDestruction == true, planet);

                                if (!allied && user.Faction != null && (user.Faction == attacker || user.Faction == defender))
                                {
                                    userParams["canAttackPwStructures"] = "1";
                                }

                                userParams["pwInstructions"] = Convert.ToBase64String(Encoding.UTF8.GetBytes(GetPwInstructions(planet, user, db, attacker)));
                            }

                            if (accountIDsWithExtraComms.Contains(user.AccountID))
                            {
                                userParams["extracomm"] = "1";
                            }

                            var commProfileIDs       = new LuaTable();
                            var userCommandersBanned = Punishment.GetActivePunishment(user.AccountID, null, null, x => x.BanCommanders) != null;
                            if (!userCommandersBanned)
                            {
                                // set up commander data
                                foreach (var c in user.Commanders.Where(x => x.Unlock != null && x.ProfileNumber <= GlobalConst.CommanderProfileCount)
                                         )
                                {
                                    try
                                    {
                                        var commProfile = new LuaTable();

                                        if (string.IsNullOrEmpty(c.Name) || c.Name.Any(x => x == '"'))
                                        {
                                            c.Name = c.CommanderID.ToString();
                                        }
                                        commProfiles.Add("c" + c.CommanderID, commProfile);
                                        commProfileIDs.Add("c" + c.CommanderID);

                                        // process decoration icons
                                        var decorations = new LuaTable();
                                        foreach (var d in
                                                 c.CommanderDecorations.Where(x => x.Unlock != null).OrderBy(x => x.SlotID).Select(x => x.Unlock))
                                        {
                                            var iconData = db.CommanderDecorationIcons.FirstOrDefault(x => x.DecorationUnlockID == d.UnlockID);
                                            if (iconData != null)
                                            {
                                                string iconName = null, iconPosition = null;
                                                // FIXME: handle avatars and preset/custom icons
                                                if (iconData.IconType == (int)DecorationIconTypes.Faction)
                                                {
                                                    iconName = user.Faction != null ? user.Faction.Shortcut : null;
                                                }
                                                else if (iconData.IconType == (int)DecorationIconTypes.Clan)
                                                {
                                                    iconName = user.Clan != null ? user.Clan.Shortcut : null;
                                                }

                                                if (iconName != null)
                                                {
                                                    iconPosition = CommanderDecoration.GetIconPosition(d);
                                                    var entry = new LuaTable();
                                                    entry.Add("image", iconName);
                                                    decorations.Add("icon_" + iconPosition.ToLower(), entry);
                                                }
                                            }
                                            else
                                            {
                                                decorations.Add(d.Code);
                                            }
                                        }

                                        commProfile["name"]        = c.Name.Substring(0, Math.Min(25, c.Name.Length));
                                        commProfile["chassis"]     = c.Unlock.Code;
                                        commProfile["decorations"] = decorations;

                                        var modules = new LuaTable();
                                        commProfile["modules"] = modules;

                                        for (var i = 1; i <= GlobalConst.NumCommanderLevels; i++)
                                        {
                                            var modulesForLevel = new LuaTable();
                                            modules.Add(modulesForLevel);
                                            var modulesOrdered = c.CommanderModules.Where(x => x.CommanderSlot.MorphLevel == i).ToList();
                                            var slots          = db.CommanderSlots.ToList().Where(x => x.MorphLevel == i && (x.ChassisID == null || (x.ChassisID == c.ChassisUnlockID))).ToList();
                                            slots.Sort(delegate(CommanderSlot x, CommanderSlot y)
                                            {
                                                UnlockTypes type1 = x.UnlockType;
                                                UnlockTypes type2 = y.UnlockType;
                                                if (type1 == UnlockTypes.WeaponManualFire || type1 == UnlockTypes.WeaponBoth)
                                                {
                                                    type1 = UnlockTypes.Weapon;
                                                }
                                                if (type2 == UnlockTypes.WeaponManualFire || type2 == UnlockTypes.WeaponBoth)
                                                {
                                                    type2 = UnlockTypes.Weapon;
                                                }
                                                int result = type1.CompareTo(type2);
                                                if (result == 0)
                                                {
                                                    return(x.CommanderSlotID.CompareTo(y.CommanderSlotID));
                                                }
                                                else
                                                {
                                                    return(result);
                                                }
                                            });
                                            foreach (var slot in slots)
                                            {
                                                String value  = String.Empty;
                                                var    module = c.CommanderModules.FirstOrDefault(x => x.SlotID == slot.CommanderSlotID);
                                                if (module != null)
                                                {
                                                    value = module.Unlock.Code;
                                                }
                                                modulesForLevel.Add(value);
                                            }
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        Trace.TraceError(ex.ToString());
                                        throw new ApplicationException(
                                                  $"Error processing commander: {c.CommanderID} - {c.Name} of player {user.AccountID} - {user.Name}",
                                                  ex);
                                    }
                                }
                            }
                            else
                            {
                                userParams["jokecomm"] = "1";
                            }

                            userParams["commanders"] = commProfileIDs.ToBase64String();
                        }
                    }
                }
                ret.ModOptions["commanderTypes"] = commProfiles.ToBase64String();

                // set PW structures
                if (mode == AutohostMode.Planetwars)
                {
                    var owner = planet.Faction != null ? planet.Faction.Shortcut : "";

                    var pwStructures = new LuaTable();
                    foreach (
                        var s in planet.PlanetStructures.Where(x => x.StructureType != null && !string.IsNullOrEmpty(x.StructureType.IngameUnitName)))
                    {
                        pwStructures.Add(s.StructureType.IngameUnitName,
                                         new LuaTable
                        {
                            { "unitname", s.StructureType.IngameUnitName },
                            { "owner", s.Account?.Name },
                            { "canBeEvacuated", s.StructureType.IsIngameEvacuable },
                            { "canBeDestroyed", s.StructureType.IsIngameDestructible },
                            //{ "isDestroyed", s.IsDestroyed ? true : false },
                            {
                                "name", $"{owner} {s.StructureType.Name} ({(s.Account != null ? s.Account.Name : "unowned")})"
                            },
                            { "description", s.StructureType.Description }
                        });
                    }
                    ret.ModOptions["planetwarsStructures"] = pwStructures.ToBase64String();
                }

                return(ret);
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                throw;
            }
        }
        protected void SendClientMissionMessage()
        {
            // 真正向服务器发, to do
            LuaTable result = new LuaTable();

            LuaTable temp;
            Mogo.RPC.Utils.PackLuaTable(localAvatarCollectedDrops, out temp);
            result.Add(1, temp);
            result.Add(2, localAvatarCollectedMoney);
            result.Add(3, localAvatarCollectedExp);

            MogoWorld.thePlayer.RpcCall("MissionExReq", (byte)MissionHandleCode.UPLOAD_COMBO_AND_BOTTLE, (ushort)localAvatarCombo, (ushort)localAvatarBottle, (ushort)(localServerAvatar.defaultReviveTimes - localServerAvatar.reviveTimes), Mogo.RPC.Utils.PackLuaTable(result));
        }
Example #28
0
 public static bool MsgUnPackTable(out LuaTable luatable, ref MessagePackObject pObj)
 {
     LuaTable result = new LuaTable();
     luatable = result;
     var mPk = pObj.AsDictionary();
     bool isString = false;
     string key;
     object value;
     foreach (var item in mPk)
     {
         //parse for key
         MessagePackObject mKey = item.Key;
         if (mKey.IsRaw)
         {
             key = mKey.AsString();
             isString = true;
         }
         else if (true == mKey.IsTypeOf<double>())
         {
             key = mKey.AsDouble().ToString();
         }
         else
         {
             LoggerHelper.Error("key type error");
             return false;
         }
         //parse for value
         MessagePackObject mValue = item.Value;
         if (mValue.IsRaw)
         {
             value = mValue.AsString();
         }
         else if (mValue.IsDictionary)
         {
             LuaTable luatbl;
             MsgUnPackTable(out luatbl, ref mValue);
             value = luatbl;
         }
         else if (true == mValue.IsTypeOf<bool>())
         {
             value = mValue.AsBoolean();
         }
         else if (true == mValue.IsTypeOf<double>())
         {
             value = mValue.AsDouble();
         }
         else
         {
             LoggerHelper.Error("value type error");
             return false;
         }
         result.Add(key, isString, value);
         isString = false;
     }
     return true;
 }
Example #29
0
        /// <summary>
        ///     Sets up all the things that Springie needs to know for the battle: how to balance, who to get extra commanders,
        ///     what PlanetWars structures to create, etc.
        /// </summary>
        public static LobbyHostingContext GetDedicatedServerStartSetup(LobbyHostingContext context)
        {
            var ret = context;

            try
            {
                var mode = context.Mode;

                var commProfiles = new LuaTable();
                var db           = new ZkDataContext();

                // calculate to whom to send extra comms
                var accountIDsWithExtraComms = new Dictionary <int, int>();
                if (mode == AutohostMode.Planetwars || mode == AutohostMode.GameFFA || mode == AutohostMode.Teams)
                {
                    var groupedByTeam = context.Players.Where(x => !x.IsSpectator).GroupBy(x => x.AllyID).OrderByDescending(x => x.Count());
                    var biggest       = groupedByTeam.FirstOrDefault();
                    if (biggest != null)
                    {
                        foreach (var other in groupedByTeam.Skip(1))
                        {
                            var cnt = biggest.Count() - other.Count();
                            if (cnt > 0)
                            {
                                // example case: 3 players on this team, 8 players on largest team
                                // 5 bonus comms to dole out to this team
                                // per_player = 1 (integer result of 5/3)
                                // remainder: 2, so now cnt = 2
                                // iterate over all players in this team
                                //  first player: cnt == 2, >0 so we give him a second extra comm
                                //  second player: cnt == 1, >0 so same deal
                                //  from now on cnt <= 0 so the last player only gets the one extra comm
                                int per_player = cnt / other.Count();
                                cnt = cnt % other.Count();
                                foreach (var a in other
                                         .Select(x => db.Accounts.First(y => y.AccountID == x.LobbyID))
                                         .OrderByDescending(x => x.GetRating(RatingCategory.Casual).Elo))
                                {
                                    accountIDsWithExtraComms.Add(a.AccountID, per_player + (cnt > 0 ? 1 : 0));
                                    cnt--;
                                }
                            }
                        }
                    }
                }


                // write Planetwars details to modoptions (for widget)
                Faction attacker = null;
                Faction defender = null;
                Planet  planet   = null;
                if (mode == AutohostMode.Planetwars)
                {
                    var galaxy = db.Galaxies.First(x => x.IsDefault);
                    planet   = galaxy.Planets.First(x => x.Resource.InternalName == context.Map);
                    attacker =
                        context.Players.Where(x => x.AllyID == 0 && !x.IsSpectator)
                        .Select(x => db.Accounts.First(y => y.AccountID == x.LobbyID))
                        .Where(x => x.Faction != null)
                        .Select(x => x.Faction)
                        .First();

                    defender = planet.Faction;

                    if (attacker == defender)
                    {
                        defender = null;
                    }

                    ret.ModOptions["attackingFaction"]      = attacker.Shortcut;
                    ret.ModOptions["attackingFactionName"]  = attacker.Name;
                    ret.ModOptions["attackingFactionColor"] = attacker.Color;
                    if (defender != null)
                    {
                        ret.ModOptions["defendingFaction"]      = defender.Shortcut;
                        ret.ModOptions["defendingFactionName"]  = defender.Name;
                        ret.ModOptions["defendingFactionColor"] = defender.Color;
                    }
                    else
                    {
                        ret.ModOptions["defendingFaction"]      = "Mercenary";
                        ret.ModOptions["defendingFactionName"]  = "Local militia";
                        ret.ModOptions["defendingFactionColor"] = "#CCCCCC";
                    }
                    ret.ModOptions["planet"]        = planet.Name;
                    ret.ModOptions["pw_galaxyTurn"] = galaxy.Turn.ToString();

                    ret.ModOptions["pw_baseIP"]            = GlobalConst.BaseInfluencePerBattle.ToString(CultureInfo.InvariantCulture);
                    ret.ModOptions["pw_dropshipIP"]        = planet.GetEffectiveShipIpBonus(attacker).ToString(CultureInfo.InvariantCulture);
                    ret.ModOptions["pw_defenseIP"]         = planet.GetEffectiveIpDefense().ToString(CultureInfo.InvariantCulture);
                    ret.ModOptions["pw_attackerIP"]        = (planet.PlanetFactions.FirstOrDefault(x => x.FactionID == attacker.FactionID)?.Influence ?? 0).ToString(CultureInfo.InvariantCulture);
                    ret.ModOptions["pw_maxIP"]             = GlobalConst.PlanetWarsMaximumIP.ToString(CultureInfo.InvariantCulture);
                    ret.ModOptions["pw_neededIP"]          = GlobalConst.InfluenceToCapturePlanet.ToString(CultureInfo.InvariantCulture);
                    ret.ModOptions["pw_attackerWinLoseCC"] = GlobalConst.PlanetWarsAttackerWinLoseCcMultiplier.ToString(CultureInfo.InvariantCulture);
                    ret.ModOptions["pw_defenderWinKillCC"] = GlobalConst.PlanetWarsDefenderWinKillCcMultiplier.ToString(CultureInfo.InvariantCulture);
                }

                // write player custom keys (level, elo, is muted, etc.)
                foreach (var p in context.Players)
                {
                    var user = db.Accounts.Where(x => x.AccountID == p.LobbyID).Include(x => x.RelalationsByOwner).FirstOrDefault();
                    if (user != null)
                    {
                        var userParams = new Dictionary <string, string>();
                        ret.UserParameters[p.Name] = userParams;

                        userParams["LobbyID"]     = user.AccountID.ToString();
                        userParams["CountryCode"] = user.HideCountry ? "??" : user.Country;

                        var userBanMuted = Punishment.GetActivePunishment(user.AccountID, null, null, null, x => x.BanMute) != null;
                        if (userBanMuted)
                        {
                            userParams["muted"] = "1";
                        }
                        userParams["faction"]  = user.Faction != null ? user.Faction.Shortcut : "";
                        userParams["clan"]     = user.Clan != null ? user.Clan.Shortcut : "";
                        userParams["clanfull"] = user.Clan != null ? user.Clan.ClanName : "";

                        userParams["level"] = user.Level.ToString();
                        //userParams["mm_elo"] = Math.Round(user.EffectiveMmElo).ToString();
                        //userParams["casual_elo"] = Math.Round(user.EffectiveElo).ToString();

                        userParams["elo"]       = Math.Round(user.GetRating(context.ApplicableRating).Elo).ToString();
                        userParams["elo_order"] = context.Players.Where(x => !x.IsSpectator)
                                                  .Select(x => db.Accounts.First(y => y.AccountID == x.LobbyID))
                                                  .Where(x => x.GetRating(context.ApplicableRating).Elo > user.GetRating(context.ApplicableRating).Elo)
                                                  .Count()
                                                  .ToString();

                        userParams["icon"]      = user.GetIconName();
                        userParams["avatar"]    = user.Avatar;
                        userParams["badges"]    = string.Join(",", user.GetBadges());
                        userParams["admin"]     = user.AdminLevel >= AdminLevel.Moderator ? "1" : "0";
                        userParams["room_boss"] = p.Name == context.FounderName ? "1" : "0";
                        if (p.PartyID.HasValue)
                        {
                            userParams["PartyID"] = p.PartyID.ToString();
                        }

                        var userSpecChatBlocked = Punishment.GetActivePunishment(user.AccountID, null, null, null, x => x.BanSpecChat) != null;;
                        userParams["can_spec_chat"] = userSpecChatBlocked ? "0" : "1";

                        userParams["ignored"] = string.Join(",", user.RelalationsByOwner.Where(x => x.Relation == Relation.Ignore).Select(x => x.Target.Name));
                        userParams["friends"] = string.Join(",", user.RelalationsByOwner.Where(x => x.Relation == Relation.Friend).Select(x => x.Target.Name));

                        if (!p.IsSpectator)
                        {
                            // set valid PW structure attackers
                            if (mode == AutohostMode.Planetwars)
                            {
                                userParams["pwRank"] = (user.AccountRolesByAccountID.Where(
                                                            x =>
                                                            !x.RoleType.IsClanOnly &&
                                                            (x.RoleType.RestrictFactionID == null || x.RoleType.RestrictFactionID == user.FactionID)).OrderBy(x => x.RoleType.DisplayOrder).Select(x => (int?)x.RoleType.DisplayOrder).FirstOrDefault() ?? 999).ToString();


                                var allied = user.Faction != null && defender != null && user.Faction != defender &&
                                             defender.HasTreatyRight(user.Faction, x => x.EffectPreventIngamePwStructureDestruction == true, planet);

                                if (!allied && user.Faction != null && (user.Faction == attacker || user.Faction == defender))
                                {
                                    userParams["canAttackPwStructures"] = "1";
                                }

                                userParams["pwInstructions"] = Convert.ToBase64String(Encoding.UTF8.GetBytes(GetPwInstructions(planet, user, db, attacker)));
                            }

                            if (accountIDsWithExtraComms.ContainsKey(user.AccountID))
                            {
                                userParams["extracomm"] = accountIDsWithExtraComms[user.AccountID].ToString();
                            }

                            var commProfileIDs       = new LuaTable();
                            var userCommandersBanned = Punishment.GetActivePunishment(user.AccountID, null, null, null, x => x.BanCommanders) != null;
                            if (!userCommandersBanned)
                            {
                                // set up commander data
                                foreach (var c in user.Commanders.Where(x => x.Unlock != null && x.ProfileNumber <= GlobalConst.CommanderProfileCount)
                                         )
                                {
                                    try
                                    {
                                        var commProfile = new LuaTable();

                                        if (string.IsNullOrEmpty(c.Name) || c.Name.Any(x => x == '"'))
                                        {
                                            c.Name = c.CommanderID.ToString();
                                        }
                                        commProfiles.Add("c" + c.CommanderID, commProfile);
                                        commProfileIDs.Add("c" + c.CommanderID);

                                        // process decoration icons
                                        var decorations = new LuaTable();
                                        foreach (var d in
                                                 c.CommanderDecorations.Where(x => x.Unlock != null).OrderBy(x => x.SlotID).Select(x => x.Unlock))
                                        {
                                            var iconData = db.CommanderDecorationIcons.FirstOrDefault(x => x.DecorationUnlockID == d.UnlockID);
                                            if (iconData != null)
                                            {
                                                string iconName = null, iconPosition = null;
                                                // FIXME: handle avatars and preset/custom icons
                                                if (iconData.IconType == (int)DecorationIconTypes.Faction)
                                                {
                                                    iconName = user.Faction != null ? user.Faction.Shortcut : null;
                                                }
                                                else if (iconData.IconType == (int)DecorationIconTypes.Clan)
                                                {
                                                    iconName = user.Clan != null ? user.Clan.Shortcut : null;
                                                }

                                                if (iconName != null)
                                                {
                                                    iconPosition = CommanderDecoration.GetIconPosition(d);
                                                    var entry = new LuaTable();
                                                    entry.Add("image", iconName);
                                                    decorations.Add("icon_" + iconPosition.ToLower(), entry);
                                                }
                                            }
                                            else
                                            {
                                                decorations.Add(d.Code);
                                            }
                                        }

                                        commProfile["name"]        = LuaTable.SanitizeString(c.Name.Substring(0, Math.Min(25, c.Name.Length))) ?? "dummy";
                                        commProfile["chassis"]     = c.Unlock.Code;
                                        commProfile["decorations"] = decorations;

                                        var modules = new LuaTable();
                                        commProfile["modules"] = modules;

                                        for (var i = 1; i <= GlobalConst.NumCommanderLevels; i++)
                                        {
                                            var modulesForLevel = new LuaTable();
                                            modules.Add(modulesForLevel);
                                            //var modulesOrdered = c.CommanderModules.Where(x => x.CommanderSlot.MorphLevel == i).ToList();
                                            var slots = db.CommanderSlots.ToList().Where(x => x.MorphLevel == i && (x.ChassisID == null || (x.ChassisID == c.ChassisUnlockID))).ToList();
                                            slots.Sort(delegate(CommanderSlot x, CommanderSlot y)
                                            {
                                                UnlockTypes type1 = x.UnlockType;
                                                UnlockTypes type2 = y.UnlockType;
                                                if (type1 == UnlockTypes.WeaponManualFire || type1 == UnlockTypes.WeaponBoth)
                                                {
                                                    type1 = UnlockTypes.Weapon;
                                                }
                                                if (type2 == UnlockTypes.WeaponManualFire || type2 == UnlockTypes.WeaponBoth)
                                                {
                                                    type2 = UnlockTypes.Weapon;
                                                }
                                                int result = type1.CompareTo(type2);
                                                if (result == 0)
                                                {
                                                    return(x.CommanderSlotID.CompareTo(y.CommanderSlotID));
                                                }
                                                else
                                                {
                                                    return(result);
                                                }
                                            });
                                            foreach (var slot in slots)
                                            {
                                                String value  = String.Empty;
                                                var    module = c.CommanderModules.FirstOrDefault(x => x.SlotID == slot.CommanderSlotID);
                                                if (module != null)
                                                {
                                                    value = module.Unlock.Code;
                                                }
                                                modulesForLevel.Add(value);
                                            }
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        Trace.TraceError(ex.ToString());
                                        throw new ApplicationException(
                                                  $"Error processing commander: {c.CommanderID} - {c.Name} of player {user.AccountID} - {user.Name}",
                                                  ex);
                                    }
                                }
                            }
                            else
                            {
                                userParams["jokecomm"] = "1";
                            }

                            userParams["commanders"] = commProfileIDs.ToBase64String();
                        }
                    }
                }
                ret.ModOptions["commanderTypes"] = commProfiles.ToBase64String();

                /* General-purpose identifier.
                 * Prefer the more specific ones below when possible */
                ret.ModOptions["serverType"] = "ZKLS";

                /* Access to commands normally accessible only by the host.
                 * Lua calls prepend the / on their own, but not the autohost,
                 * so /say doesn't need it, but the cheat command does */
                ret.ModOptions["cheatCommandPrefix"] = "say !hostsay /";

                /* The server is listening for SPRINGIE strings (the game can skip those otherwise).
                 * See https://github.com/ZeroK-RTS/Zero-K-Infrastructure/blob/master/Shared/LobbyClient/DedicatedServer.cs#L317 */
                ret.ModOptions["sendSpringieData"] = "1";

                // set PW structures
                if (mode == AutohostMode.Planetwars)
                {
                    var owner = planet.Faction != null ? planet.Faction.Shortcut : "";

                    var pwStructures = new LuaTable();
                    foreach (
                        var s in planet.PlanetStructures.Where(x => x.StructureType != null && !string.IsNullOrEmpty(x.StructureType.IngameUnitName)))
                    {
                        pwStructures.Add(s.StructureType.IngameUnitName,
                                         new LuaTable
                        {
                            { "unitname", s.StructureType.IngameUnitName },
                            { "owner", s.Account?.Name },
                            { "canBeEvacuated", s.StructureType.IsIngameEvacuable },
                            { "canBeDestroyed", s.StructureType.IsIngameDestructible },
                            { "isInactive", !s.IsActive },
                            {
                                "name", $"{owner} {s.StructureType.Name} ({(s.Account != null ? s.Account.Name : "unowned")})"
                            },
                            { "description", s.StructureType.Description }
                        });
                    }
                    ret.ModOptions["planetwarsStructures"] = pwStructures.ToBase64String();
                }

                return(ret);
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                throw;
            }
        }
        static bool listOnlyThatLevelsModules = false;  // may cause bugs

        public static SpringBattleStartSetup GetSpringBattleStartSetup(BattleContext context) {
            try {
                AutohostMode mode = context.GetMode();
                var ret = new SpringBattleStartSetup();

                if (mode == AutohostMode.Planetwars)
                {
                    ret.BalanceTeamsResult = Balancer.BalanceTeams(context, true,null, null);
                    context.Players = ret.BalanceTeamsResult.Players;
                }
                
                var commanderTypes = new LuaTable();
                var db = new ZkDataContext();

                var accountIDsWithExtraComms = new List<int>();
                // calculate to whom to send extra comms
                if (mode == AutohostMode.Planetwars || mode == AutohostMode.Generic || mode == AutohostMode.GameFFA ||
                    mode == AutohostMode.Teams) {
                    IOrderedEnumerable<IGrouping<int, PlayerTeam>> groupedByTeam =
                        context.Players.Where(x => !x.IsSpectator).GroupBy(x => x.AllyID).OrderByDescending(x => x.Count());
                    IGrouping<int, PlayerTeam> biggest = groupedByTeam.FirstOrDefault();
                    if (biggest != null) {
                        foreach (var other in groupedByTeam.Skip(1)) {
                            int cnt = biggest.Count() - other.Count();
                            if (cnt > 0) {
                                foreach (Account a in
                                    other.Select(x => db.Accounts.First(y => y.AccountID == x.LobbyID)).OrderByDescending(x => x.Elo*x.EloWeight).Take(
                                        cnt)) accountIDsWithExtraComms.Add(a.AccountID);
                            }
                        }
                    }
                }

                bool is1v1 = context.Players.Where(x => !x.IsSpectator).ToList().Count == 2 && context.Bots.Count == 0;



                Faction attacker = null;
                Faction defender = null;
                Planet planet = null;
                if (mode == AutohostMode.Planetwars) {
                    planet = db.Galaxies.First(x => x.IsDefault).Planets.First(x => x.Resource.InternalName == context.Map);
                    attacker =
                        context.Players.Where(x => x.AllyID == 0 && !x.IsSpectator)
                            .Select(x => db.Accounts.First(y => y.AccountID == x.LobbyID))
                            .Where(x => x.Faction != null)
                            .Select(x => x.Faction)
                            .First();

                    defender = planet.Faction;

                    if (attacker == defender) defender = null;

                    ret.ModOptions.Add(new SpringBattleStartSetup.ScriptKeyValuePair { Key = "attackingFaction", Value = attacker.Shortcut });
                    if (defender != null) ret.ModOptions.Add(new SpringBattleStartSetup.ScriptKeyValuePair { Key = "defendingFaction", Value = defender.Shortcut });
                    ret.ModOptions.Add(new SpringBattleStartSetup.ScriptKeyValuePair { Key = "planet", Value = planet.Name });
                }


                
                foreach (PlayerTeam p in context.Players) {
                    Account user = db.Accounts.Find(p.LobbyID);
                    if (user != null) {
                        var userParams = new List<SpringBattleStartSetup.ScriptKeyValuePair>();
                        ret.UserParameters.Add(new SpringBattleStartSetup.UserCustomParameters { LobbyID = p.LobbyID, Parameters = userParams });

                        bool userBanMuted = user.PunishmentsByAccountID.Any(x => !x.IsExpired && x.BanMute);
                        if (userBanMuted) userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair { Key = "muted", Value = "1" });
                        userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair
                                       { Key = "faction", Value = user.Faction != null ? user.Faction.Shortcut : "" });
                        userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair
                                       { Key = "clan", Value = user.Clan != null ? user.Clan.Shortcut : "" });
                        userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair { Key = "level", Value = user.Level.ToString() });
                        double elo =  mode == AutohostMode.Planetwars ? user.EffectivePwElo : (is1v1 ? user.Effective1v1Elo : user.EffectiveElo);
                        userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair { Key = "elo", Value = Math.Round(elo).ToString() }); // elo for ingame is just ordering for auto /take
                        userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair { Key = "avatar", Value = user.Avatar });
                        userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair { Key = "admin", Value = (user.IsZeroKAdmin ? "1" : "0") });

                        if (!p.IsSpectator) {
                            if (mode == AutohostMode.Planetwars)
                            {
                                bool allied = user.Faction != null && defender != null && user.Faction != defender &&
                                              defender.HasTreatyRight(user.Faction, x => x.EffectPreventIngamePwStructureDestruction == true, planet);

                                if (!allied && user.Faction != null && (user.Faction == attacker || user.Faction == defender)) {
                                    userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair { Key = "canAttackPwStructures", Value = "1" });
                                }
                            }

                            var pu = new LuaTable();
                            bool userUnlocksBanned = user.PunishmentsByAccountID.Any(x => !x.IsExpired && x.BanUnlocks);
                            bool userCommandersBanned = user.PunishmentsByAccountID.Any(x => !x.IsExpired && x.BanCommanders);

                            if (!userUnlocksBanned) {
                                if (mode != AutohostMode.Planetwars || user.Faction == null) foreach (Unlock unlock in user.AccountUnlocks.Select(x => x.Unlock)) pu.Add(unlock.Code);
                                else {
                                    foreach (Unlock unlock in
                                        user.AccountUnlocks.Select(x => x.Unlock).Union(user.Faction.GetFactionUnlocks().Select(x => x.Unlock)).Where(x => x.UnlockType == UnlockTypes.Unit)) pu.Add(unlock.Code);
                                }
                            }

                            userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair { Key = "unlocks", Value = pu.ToBase64String() });

                            if (accountIDsWithExtraComms.Contains(user.AccountID)) userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair { Key = "extracomm", Value = "1" });

                            var pc = new LuaTable();

                            if (!userCommandersBanned) {
                                foreach (Commander c in user.Commanders.Where(x => x.Unlock != null && x.ProfileNumber <= GlobalConst.CommanderProfileCount)) {
                                    try {
                                        if (string.IsNullOrEmpty(c.Name) || c.Name.Any(x => x == '"') )
                                        {
                                            c.Name = c.CommanderID.ToString();
                                        }
                                        LuaTable morphTable = new LuaTable();
                                        pc["[\"" + c.Name + "\"]"] = morphTable;

                                        // process decoration icons
                                        LuaTable decorations = new LuaTable();
                                        foreach (Unlock d in
                                                        c.CommanderDecorations.Where(x => x.Unlock != null).OrderBy(
                                                            x => x.SlotID).Select(x => x.Unlock))
                                        {
                                            CommanderDecorationIcon iconData = db.CommanderDecorationIcons.FirstOrDefault(x => x.DecorationUnlockID == d.UnlockID);
                                            if (iconData != null)
                                            {
                                                string iconName = null, iconPosition = null;
                                                // FIXME: handle avatars and preset/custom icons
                                                if (iconData.IconType == (int)DecorationIconTypes.Faction)
                                                {
                                                    iconName = user.Faction != null ? user.Faction.Shortcut : null;
                                                }
                                                else if (iconData.IconType == (int)DecorationIconTypes.Clan)
                                                {
                                                    iconName = user.Clan != null ? user.Clan.Shortcut : null;
                                                }

                                                if (iconName != null)
                                                {
                                                    iconPosition = CommanderDecoration.GetIconPosition(d);
                                                    LuaTable entry = new LuaTable();
                                                    entry.Add("image", iconName);
                                                    decorations.Add("icon_" + iconPosition.ToLower(), entry);
                                                }
                                            }
                                            else decorations.Add(d.Code);
                                        }
                                        

                                        string prevKey = null;
                                        for (int i = 0; i <= GlobalConst.NumCommanderLevels; i++) {
                                            string key = string.Format("c{0}_{1}_{2}", user.AccountID, c.ProfileNumber, i);
                                            morphTable.Add(key);    // TODO: maybe don't specify morph series in player data, only starting unit

                                            var comdef = new LuaTable();
                                            commanderTypes[key] = comdef;

                                            comdef["chassis"] = c.Unlock.Code + i;

                                            var modules = new LuaTable();
                                            comdef["modules"] = modules;
                                            
                                            comdef["decorations"] = decorations;

                                            comdef["name"] = c.Name.Substring(0, Math.Min(25, c.Name.Length)) + " level " + i;

                                            //if (i < GlobalConst.NumCommanderLevels)
                                            //{
                                            //    comdef["next"] = string.Format("c{0}_{1}_{2}", user.AccountID, c.ProfileNumber, i+1);
                                            //}
                                            //comdef["owner"] = user.Name;

                                            if (i > 0)
                                            {
                                                comdef["cost"] = c.GetTotalMorphLevelCost(i);

                                                if (listOnlyThatLevelsModules)
                                                {
                                                    if (prevKey != null) comdef["prev"] = prevKey;
                                                    prevKey = key;
                                                    foreach (Unlock m in
                                                        c.CommanderModules.Where(x => x.CommanderSlot.MorphLevel == i && x.Unlock != null).OrderBy(
                                                            x => x.Unlock.UnlockType).ThenBy(x => x.SlotID).Select(x => x.Unlock)) modules.Add(m.Code);
                                                }
                                                else
                                                {
                                                    foreach (Unlock m in
                                                        c.CommanderModules.Where(x => x.CommanderSlot.MorphLevel <= i && x.Unlock != null).OrderBy(
                                                            x => x.Unlock.UnlockType).ThenBy(x => x.SlotID).Select(x => x.Unlock)) modules.Add(m.Code);
                                                }
                                            }
                                        }
                                    } catch (Exception ex) {
                                        Trace.TraceError(ex.ToString());
                                        throw new ApplicationException(
                                            string.Format("Error processing commander: {0} - {1} of player {2} - {3}",
                                                          c.CommanderID,
                                                          c.Name,
                                                          user.AccountID,
                                                          user.Name),
                                            ex);
                                    }
                                }
                            }
                            else userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair { Key = "jokecomm", Value = "1" });

                            userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair { Key = "commanders", Value = pc.ToBase64String() });
                        }
                    }
                }

                ret.ModOptions.Add(new SpringBattleStartSetup.ScriptKeyValuePair { Key = "commanderTypes", Value = commanderTypes.ToBase64String() });
                if (mode == AutohostMode.Planetwars)
                {
                    string owner = planet.Faction != null ? planet.Faction.Shortcut : "";

                    var pwStructures = new LuaTable();
                    foreach (PlanetStructure s in planet.PlanetStructures.Where(x => x.StructureType!= null && !string.IsNullOrEmpty(x.StructureType.IngameUnitName))) {
                        pwStructures.Add("s" + s.StructureTypeID,
                                         new LuaTable
                                         {
                                             { "unitname", s.StructureType.IngameUnitName },
                                             //{ "isDestroyed", s.IsDestroyed ? true : false },
                                             { "name", string.Format("{0} {1} ({2})", owner, s.StructureType.Name, s.Account!= null ? s.Account.Name:"unowned") },
                                             { "description", s.StructureType.Description }
                                         });
                    }
                    ret.ModOptions.Add(new SpringBattleStartSetup.ScriptKeyValuePair
                                       { Key = "planetwarsStructures", Value = pwStructures.ToBase64String() });
                }

                return ret;
            } catch (Exception ex) {
                Trace.TraceError(ex.ToString());
                throw;
            }
        }
        static bool listOnlyThatLevelsModules = false;  // may cause bugs

        /// <summary>
        /// Sets up all the things that Springie needs to know for the battle: how to balance, who to get extra commanders, what PlanetWars structures to create, etc.
        /// </summary>
        public static SpringBattleStartSetup GetSpringBattleStartSetup(BattleContext context)
        {
            try {
                AutohostMode mode = context.GetMode();
                var          ret  = new SpringBattleStartSetup();

                if (mode == AutohostMode.Planetwars)
                {
                    ret.BalanceTeamsResult = Balancer.BalanceTeams(context, true, null, null);
                    context.Players        = ret.BalanceTeamsResult.Players;
                }

                var commanderTypes = new LuaTable();
                var db             = new ZkDataContext();

                // calculate to whom to send extra comms
                var accountIDsWithExtraComms = new List <int>();
                if (mode == AutohostMode.Planetwars || mode == AutohostMode.Generic || mode == AutohostMode.GameFFA ||
                    mode == AutohostMode.Teams)
                {
                    IOrderedEnumerable <IGrouping <int, PlayerTeam> > groupedByTeam =
                        context.Players.Where(x => !x.IsSpectator).GroupBy(x => x.AllyID).OrderByDescending(x => x.Count());
                    IGrouping <int, PlayerTeam> biggest = groupedByTeam.FirstOrDefault();
                    if (biggest != null)
                    {
                        foreach (var other in groupedByTeam.Skip(1))
                        {
                            int cnt = biggest.Count() - other.Count();
                            if (cnt > 0)
                            {
                                foreach (Account a in
                                         other.Select(x => db.Accounts.First(y => y.AccountID == x.LobbyID)).OrderByDescending(x => x.Elo * x.EloWeight).Take(
                                             cnt))
                                {
                                    accountIDsWithExtraComms.Add(a.AccountID);
                                }
                            }
                        }
                    }
                }

                bool is1v1 = context.Players.Where(x => !x.IsSpectator).ToList().Count == 2 && context.Bots.Count == 0;

                // write Planetwars details to modoptions (for widget)
                Faction attacker = null;
                Faction defender = null;
                Planet  planet   = null;
                if (mode == AutohostMode.Planetwars)
                {
                    planet   = db.Galaxies.First(x => x.IsDefault).Planets.First(x => x.Resource.InternalName == context.Map);
                    attacker =
                        context.Players.Where(x => x.AllyID == 0 && !x.IsSpectator)
                        .Select(x => db.Accounts.First(y => y.AccountID == x.LobbyID))
                        .Where(x => x.Faction != null)
                        .Select(x => x.Faction)
                        .First();

                    defender = planet.Faction;

                    if (attacker == defender)
                    {
                        defender = null;
                    }

                    ret.ModOptions.Add(new SpringBattleStartSetup.ScriptKeyValuePair {
                        Key = "attackingFaction", Value = attacker.Shortcut
                    });
                    if (defender != null)
                    {
                        ret.ModOptions.Add(new SpringBattleStartSetup.ScriptKeyValuePair {
                            Key = "defendingFaction", Value = defender.Shortcut
                        });
                    }
                    ret.ModOptions.Add(new SpringBattleStartSetup.ScriptKeyValuePair {
                        Key = "planet", Value = planet.Name
                    });
                }

                // write player custom keys (level, elo, is muted, etc.)
                foreach (PlayerTeam p in context.Players)
                {
                    Account user = db.Accounts.Find(p.LobbyID);
                    if (user != null)
                    {
                        var userParams = new List <SpringBattleStartSetup.ScriptKeyValuePair>();
                        ret.UserParameters.Add(new SpringBattleStartSetup.UserCustomParameters {
                            LobbyID = p.LobbyID, Parameters = userParams
                        });

                        bool userBanMuted = user.PunishmentsByAccountID.Any(x => !x.IsExpired && x.BanMute);
                        if (userBanMuted)
                        {
                            userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair {
                                Key = "muted", Value = "1"
                            });
                        }
                        userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair
                        {
                            Key = "faction", Value = user.Faction != null ? user.Faction.Shortcut : ""
                        });
                        userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair
                        {
                            Key = "clan", Value = user.Clan != null ? user.Clan.Shortcut : ""
                        });
                        userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair {
                            Key = "level", Value = user.Level.ToString()
                        });
                        double elo = mode == AutohostMode.Planetwars ? user.EffectivePwElo : (is1v1 ? user.Effective1v1Elo : user.EffectiveElo);
                        userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair {
                            Key = "elo", Value = Math.Round(elo).ToString()
                        });                                                                                                                // elo for ingame is just ordering for auto /take
                        userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair {
                            Key = "avatar", Value = user.Avatar
                        });
                        userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair {
                            Key = "admin", Value = (user.IsZeroKAdmin ? "1" : "0")
                        });

                        if (!p.IsSpectator)
                        {
                            // set valid PW structure attackers
                            if (mode == AutohostMode.Planetwars)
                            {
                                bool allied = user.Faction != null && defender != null && user.Faction != defender &&
                                              defender.HasTreatyRight(user.Faction, x => x.EffectPreventIngamePwStructureDestruction == true, planet);

                                if (!allied && user.Faction != null && (user.Faction == attacker || user.Faction == defender))
                                {
                                    userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair {
                                        Key = "canAttackPwStructures", Value = "1"
                                    });
                                }
                            }

                            var  pu = new LuaTable();
                            bool userUnlocksBanned    = user.PunishmentsByAccountID.Any(x => !x.IsExpired && x.BanUnlocks);
                            bool userCommandersBanned = user.PunishmentsByAccountID.Any(x => !x.IsExpired && x.BanCommanders);

                            if (!userUnlocksBanned)
                            {
                                if (mode != AutohostMode.Planetwars || user.Faction == null)
                                {
                                    foreach (Unlock unlock in user.AccountUnlocks.Select(x => x.Unlock))
                                    {
                                        pu.Add(unlock.Code);
                                    }
                                }
                                else
                                {
                                    foreach (Unlock unlock in
                                             user.AccountUnlocks.Select(x => x.Unlock).Union(user.Faction.GetFactionUnlocks().Select(x => x.Unlock)).Where(x => x.UnlockType == UnlockTypes.Unit))
                                    {
                                        pu.Add(unlock.Code);
                                    }
                                }
                            }

                            userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair {
                                Key = "unlocks", Value = pu.ToBase64String()
                            });

                            if (accountIDsWithExtraComms.Contains(user.AccountID))
                            {
                                userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair {
                                    Key = "extracomm", Value = "1"
                                });
                            }

                            var pc = new LuaTable();

                            if (!userCommandersBanned)
                            {
                                // set up commander data
                                foreach (Commander c in user.Commanders.Where(x => x.Unlock != null && x.ProfileNumber <= GlobalConst.CommanderProfileCount))
                                {
                                    try {
                                        if (string.IsNullOrEmpty(c.Name) || c.Name.Any(x => x == '"'))
                                        {
                                            c.Name = c.CommanderID.ToString();
                                        }
                                        LuaTable morphTable = new LuaTable();
                                        pc["[\"" + c.Name + "\"]"] = morphTable;

                                        // process decoration icons
                                        LuaTable decorations = new LuaTable();
                                        foreach (Unlock d in
                                                 c.CommanderDecorations.Where(x => x.Unlock != null).OrderBy(
                                                     x => x.SlotID).Select(x => x.Unlock))
                                        {
                                            CommanderDecorationIcon iconData = db.CommanderDecorationIcons.FirstOrDefault(x => x.DecorationUnlockID == d.UnlockID);
                                            if (iconData != null)
                                            {
                                                string iconName = null, iconPosition = null;
                                                // FIXME: handle avatars and preset/custom icons
                                                if (iconData.IconType == (int)DecorationIconTypes.Faction)
                                                {
                                                    iconName = user.Faction != null ? user.Faction.Shortcut : null;
                                                }
                                                else if (iconData.IconType == (int)DecorationIconTypes.Clan)
                                                {
                                                    iconName = user.Clan != null ? user.Clan.Shortcut : null;
                                                }

                                                if (iconName != null)
                                                {
                                                    iconPosition = CommanderDecoration.GetIconPosition(d);
                                                    LuaTable entry = new LuaTable();
                                                    entry.Add("image", iconName);
                                                    decorations.Add("icon_" + iconPosition.ToLower(), entry);
                                                }
                                            }
                                            else
                                            {
                                                decorations.Add(d.Code);
                                            }
                                        }


                                        string prevKey = null;
                                        for (int i = 0; i <= GlobalConst.NumCommanderLevels; i++)
                                        {
                                            string key = string.Format("c{0}_{1}_{2}", user.AccountID, c.ProfileNumber, i);
                                            morphTable.Add(key);    // TODO: maybe don't specify morph series in player data, only starting unit

                                            var comdef = new LuaTable();
                                            commanderTypes[key] = comdef;

                                            comdef["chassis"] = c.Unlock.Code + i;

                                            var modules = new LuaTable();
                                            comdef["modules"] = modules;

                                            comdef["decorations"] = decorations;

                                            comdef["name"] = c.Name.Substring(0, Math.Min(25, c.Name.Length)) + " level " + i;

                                            //if (i < GlobalConst.NumCommanderLevels)
                                            //{
                                            //    comdef["next"] = string.Format("c{0}_{1}_{2}", user.AccountID, c.ProfileNumber, i+1);
                                            //}
                                            //comdef["owner"] = user.Name;

                                            if (i > 0)
                                            {
                                                comdef["cost"] = c.GetTotalMorphLevelCost(i);

                                                if (listOnlyThatLevelsModules)
                                                {
                                                    if (prevKey != null)
                                                    {
                                                        comdef["prev"] = prevKey;
                                                    }
                                                    prevKey = key;
                                                    foreach (Unlock m in
                                                             c.CommanderModules.Where(x => x.CommanderSlot.MorphLevel == i && x.Unlock != null).OrderBy(
                                                                 x => x.Unlock.UnlockType).ThenBy(x => x.SlotID).Select(x => x.Unlock))
                                                    {
                                                        modules.Add(m.Code);
                                                    }
                                                }
                                                else
                                                {
                                                    foreach (Unlock m in
                                                             c.CommanderModules.Where(x => x.CommanderSlot.MorphLevel <= i && x.Unlock != null).OrderBy(
                                                                 x => x.Unlock.UnlockType).ThenBy(x => x.SlotID).Select(x => x.Unlock))
                                                    {
                                                        modules.Add(m.Code);
                                                    }
                                                }
                                            }
                                        }
                                    } catch (Exception ex) {
                                        Trace.TraceError(ex.ToString());
                                        throw new ApplicationException(
                                                  string.Format("Error processing commander: {0} - {1} of player {2} - {3}",
                                                                c.CommanderID,
                                                                c.Name,
                                                                user.AccountID,
                                                                user.Name),
                                                  ex);
                                    }
                                }
                            }
                            else
                            {
                                userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair {
                                    Key = "jokecomm", Value = "1"
                                });
                            }

                            userParams.Add(new SpringBattleStartSetup.ScriptKeyValuePair {
                                Key = "commanders", Value = pc.ToBase64String()
                            });
                        }
                    }
                }

                ret.ModOptions.Add(new SpringBattleStartSetup.ScriptKeyValuePair {
                    Key = "commanderTypes", Value = commanderTypes.ToBase64String()
                });

                // set PW structures
                if (mode == AutohostMode.Planetwars)
                {
                    string owner = planet.Faction != null ? planet.Faction.Shortcut : "";

                    var pwStructures = new LuaTable();
                    foreach (PlanetStructure s in planet.PlanetStructures.Where(x => x.StructureType != null && !string.IsNullOrEmpty(x.StructureType.IngameUnitName)))
                    {
                        pwStructures.Add("s" + s.StructureTypeID,
                                         new LuaTable
                        {
                            { "unitname", s.StructureType.IngameUnitName },
                            //{ "isDestroyed", s.IsDestroyed ? true : false },
                            { "name", string.Format("{0} {1} ({2})", owner, s.StructureType.Name, s.Account != null ? s.Account.Name:"unowned") },
                            { "description", s.StructureType.Description }
                        });
                    }
                    ret.ModOptions.Add(new SpringBattleStartSetup.ScriptKeyValuePair
                    {
                        Key = "planetwarsStructures", Value = pwStructures.ToBase64String()
                    });
                }

                return(ret);
            } catch (Exception ex) {
                Trace.TraceError(ex.ToString());
                throw;
            }
        }
        /// <summary>
        ///     Sets up all the things that Springie needs to know for the battle: how to balance, who to get extra commanders,
        ///     what PlanetWars structures to create, etc.
        /// </summary>
        public static LobbyHostingContext GetDedicatedServerStartSetup(LobbyHostingContext context)
        {
            var ret = context;
            try
            {
                var mode = context.Mode;

               var commProfiles = new LuaTable();
                var db = new ZkDataContext();

                // calculate to whom to send extra comms
                var accountIDsWithExtraComms = new List<int>();
                if (mode == AutohostMode.Planetwars || mode == AutohostMode.GameFFA || mode == AutohostMode.Teams)
                {
                    var groupedByTeam = context.Players.Where(x => !x.IsSpectator).GroupBy(x => x.AllyID).OrderByDescending(x => x.Count());
                    var biggest = groupedByTeam.FirstOrDefault();
                    if (biggest != null)
                    {
                        foreach (var other in groupedByTeam.Skip(1))
                        {
                            var cnt = biggest.Count() - other.Count();
                            if (cnt > 0)
                            {
                                foreach (var a in
                                    other.Select(x => db.Accounts.First(y => y.AccountID == x.LobbyID))
                                        .OrderByDescending(x => x.Elo*x.EloWeight)
                                        .Take(cnt)) accountIDsWithExtraComms.Add(a.AccountID);
                            }
                        }
                    }
                }


                // write Planetwars details to modoptions (for widget)
                Faction attacker = null;
                Faction defender = null;
                Planet planet = null;
                if (mode == AutohostMode.Planetwars)
                {
                    planet = db.Galaxies.First(x => x.IsDefault).Planets.First(x => x.Resource.InternalName == context.Map);
                    attacker =
                        context.Players.Where(x => x.AllyID == 0 && !x.IsSpectator)
                            .Select(x => db.Accounts.First(y => y.AccountID == x.LobbyID))
                            .Where(x => x.Faction != null)
                            .Select(x => x.Faction)
                            .First();

                    defender = planet.Faction;

                    if (attacker == defender) defender = null;

                    ret.ModOptions["attackingFaction"] = attacker.Shortcut;
                    if (defender != null) ret.ModOptions["defendingFaction"] = defender.Shortcut;
                    ret.ModOptions["planet"] = planet.Name;
                }

                // write player custom keys (level, elo, is muted, etc.)
                foreach (var p in context.Players)
                {
                    var user = db.Accounts.Where(x=>x.AccountID == p.LobbyID).Include(x=>x.RelalationsByOwner).FirstOrDefault();
                    if (user != null)
                    {
                        var userParams = new Dictionary<string, string>();
                        ret.UserParameters[p.Name] = userParams;

                        userParams["LobbyID"] = user.AccountID.ToString();
                        userParams["CountryCode"] = user.Country;

                        var userBanMuted = user.PunishmentsByAccountID.Any(x => !x.IsExpired && x.BanMute);
                        if (userBanMuted) userParams["muted"] = "1";
                        userParams["faction"] = user.Faction != null ? user.Faction.Shortcut : "";
                        userParams["clan"] = user.Clan != null ? user.Clan.Shortcut : "";
                        userParams["clanfull"] = user.Clan != null ? user.Clan.ClanName : "";
                        userParams["level"] = user.Level.ToString();
                        var elo = user.EffectiveMmElo;
                        userParams["elo"] = Math.Round(elo).ToString(); 
                        userParams["skill_order"] = ((context.IsMatchMakerGame ? user.CompetitiveRank : user.CasualRank) ?? int.MaxValue).ToString(); // send order of skills (For lists). Note this should be improved by sendng normalized list instead of ranks

                        userParams["avatar"] = user.Avatar;
                        userParams["admin"] = user.IsZeroKAdmin ? "1" : "0";

                        var userSpecChatBlocked = user.PunishmentsByAccountID.Any(x => !x.IsExpired && x.BanSpecChat);
                        userParams["can_spec_chat"] = userSpecChatBlocked ? "0" : "1";

                        userParams["ignored"] = string.Join(",", user.RelalationsByOwner.Where(x => x.Relation == Relation.Ignore).Select(x=>x.Target.Name));
                        userParams["friends"] = string.Join(",", user.RelalationsByOwner.Where(x => x.Relation == Relation.Friend).Select(x=>x.Target.Name));
                        
                        if (!p.IsSpectator)
                        {
                            // set valid PW structure attackers
                            if (mode == AutohostMode.Planetwars)
                            {
                                var allied = user.Faction != null && defender != null && user.Faction != defender &&
                                             defender.HasTreatyRight(user.Faction, x => x.EffectPreventIngamePwStructureDestruction == true, planet);

                                if (!allied && user.Faction != null && (user.Faction == attacker || user.Faction == defender))
                                {
                                    userParams["canAttackPwStructures"] = "1";
                                }
                            }

                            if (accountIDsWithExtraComms.Contains(user.AccountID)) userParams["extracomm"] = "1";

                            var commProfileIDs = new LuaTable();
                            var userCommandersBanned = user.PunishmentsByAccountID.Any(x => !x.IsExpired && x.BanCommanders);
                            if (!userCommandersBanned)
                            {
                                // set up commander data
                                foreach (var c in user.Commanders.Where(x => x.Unlock != null && x.ProfileNumber <= GlobalConst.CommanderProfileCount)
                                    )
                                {
                                    try
                                    {
                                        var commProfile = new LuaTable();

                                        if (string.IsNullOrEmpty(c.Name) || c.Name.Any(x => x == '"'))
                                        {
                                            c.Name = c.CommanderID.ToString();
                                        }
                                        commProfiles.Add("c" + c.CommanderID, commProfile);
                                        commProfileIDs.Add("c" + c.CommanderID);

                                        // process decoration icons
                                        var decorations = new LuaTable();
                                        foreach (var d in
                                            c.CommanderDecorations.Where(x => x.Unlock != null).OrderBy(x => x.SlotID).Select(x => x.Unlock))
                                        {
                                            var iconData = db.CommanderDecorationIcons.FirstOrDefault(x => x.DecorationUnlockID == d.UnlockID);
                                            if (iconData != null)
                                            {
                                                string iconName = null, iconPosition = null;
                                                // FIXME: handle avatars and preset/custom icons
                                                if (iconData.IconType == (int)DecorationIconTypes.Faction)
                                                {
                                                    iconName = user.Faction != null ? user.Faction.Shortcut : null;
                                                }
                                                else if (iconData.IconType == (int)DecorationIconTypes.Clan)
                                                {
                                                    iconName = user.Clan != null ? user.Clan.Shortcut : null;
                                                }

                                                if (iconName != null)
                                                {
                                                    iconPosition = CommanderDecoration.GetIconPosition(d);
                                                    var entry = new LuaTable();
                                                    entry.Add("image", iconName);
                                                    decorations.Add("icon_" + iconPosition.ToLower(), entry);
                                                }
                                            }
                                            else decorations.Add(d.Code);
                                        }

                                        commProfile["name"] = c.Name.Substring(0, Math.Min(25, c.Name.Length));
                                        commProfile["chassis"] = c.Unlock.Code;
                                        commProfile["decorations"] = decorations;

                                        var modules = new LuaTable();
                                        commProfile["modules"] = modules;

                                        for (var i = 1; i <= GlobalConst.NumCommanderLevels; i++)
                                        {
                                            var modulesForLevel = new LuaTable();
                                            modules.Add(modulesForLevel);
                                            var modulesOrdered = c.CommanderModules.Where(x => x.CommanderSlot.MorphLevel == i).ToList();
                                            var slots = db.CommanderSlots.ToList().Where(x => x.MorphLevel == i && (x.ChassisID == null || (x.ChassisID == c.ChassisUnlockID))).ToList();
                                            slots.Sort(delegate (CommanderSlot x, CommanderSlot y)
                                            {
                                                UnlockTypes type1 = x.UnlockType;
                                                UnlockTypes type2 = x.UnlockType;
                                                if (type1 == UnlockTypes.WeaponManualFire || type1 == UnlockTypes.WeaponBoth)
                                                    type1 = UnlockTypes.Weapon;
                                                if (type2 == UnlockTypes.WeaponManualFire || type2 == UnlockTypes.WeaponBoth)
                                                    type2 = UnlockTypes.Weapon;
                                                int result = type1.CompareTo(type2);
                                                if (result == 0) return x.CommanderSlotID.CompareTo(y.CommanderSlotID);
                                                else return result;
                                            });
                                            foreach (var slot in slots)
                                            {
                                                String value = String.Empty;
                                                var module = c.CommanderModules.FirstOrDefault(x => x.SlotID == slot.CommanderSlotID);
                                                if (module != null)
                                                    value = module.Unlock.Code;
                                                modulesForLevel.Add(value);
                                            }
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        Trace.TraceError(ex.ToString());
                                        throw new ApplicationException(
                                            $"Error processing commander: {c.CommanderID} - {c.Name} of player {user.AccountID} - {user.Name}",
                                            ex);
                                    }
                                }
                            }
                            else userParams["jokecomm"] = "1";

                            userParams["commanders"] = commProfileIDs.ToBase64String();
                        }
                    }
                }
                ret.ModOptions["commanderTypes"] = commProfiles.ToBase64String();

                // set PW structures
                if (mode == AutohostMode.Planetwars)
                {
                    var owner = planet.Faction != null ? planet.Faction.Shortcut : "";

                    var pwStructures = new LuaTable();
                    foreach (
                        var s in planet.PlanetStructures.Where(x => x.StructureType != null && !string.IsNullOrEmpty(x.StructureType.IngameUnitName)))
                    {
                        pwStructures.Add("s" + s.StructureTypeID,
                            new LuaTable
                            {
                                { "unitname", s.StructureType.IngameUnitName },
                                //{ "isDestroyed", s.IsDestroyed ? true : false },
                                {
                                    "name", $"{owner} {s.StructureType.Name} ({(s.Account != null ? s.Account.Name : "unowned")})" },
                                { "description", s.StructureType.Description }
                            });
                    }
                    ret.ModOptions["planetwarsStructures"] = pwStructures.ToBase64String();
                }

                return ret;
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                throw;
            }
        }
Example #33
0
 /// <summary>
 /// 转换复杂类型的对象到LuaTable,不支持基础类型直接转换。
 /// </summary>
 /// <param name="target"></param>
 /// <param name="result"></param>
 /// <returns></returns>
 public static bool PackLuaTable(object target, out LuaTable result)
 {
     var type = target.GetType();
     if (type == typeof(LuaTable))
     {
         result = target as LuaTable;
         return true;
     }
     if (type.IsGenericType)
     {//容器类型
         //目前只支持列表与字典的容器类型转换
         if (type.GetGenericTypeDefinition() == typeof(Dictionary<,>))
         {
             return PackLuaTable(target as IDictionary, out result);
         }
         else
         {
             return PackLuaTable(target as IList, out result);
         }
     }
     else
     {//实体类型
         result = new LuaTable();
         try
         {
             var props = type.GetProperties(~BindingFlags.Static);
             for (int i = 0; i < props.Length; i++)
             {
                 var prop = props[i];
                 if (IsBaseType(prop.PropertyType))
                     result.Add(i + 1, prop.GetGetMethod().Invoke(target, null));
                 else
                 {
                     LuaTable lt;
                     var value = prop.GetGetMethod().Invoke(target, null);
                     var flag = PackLuaTable(value, out lt);
                     if (flag)
                         result.Add(i + 1, lt);
                 }
             }
         }
         catch (Exception ex)
         {
             LoggerHelper.Error("PackLuaTable entity error: " + ex.Message);
         }
     }
     return true;
 }