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); }
/// <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); }
/// <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); }
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)); }
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); }
private static void EncounteredString(LuaTable currentTable, string currentIdentifier, string val) { if (currentIdentifier == null) { currentIdentifier = currentTable.Count.ToString(); } currentTable.Add(currentIdentifier, new LuaValue(val)); }
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); }
} // 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
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); }
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); }
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); }
} // 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
/// <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); }
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); }
/// <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); }
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); } }
} // 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
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"); } }
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; }
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; }
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; } }
/// <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; }
/// <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; }
/// <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; } }
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; }
/// <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; } }
/// <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; }