public ActionResult ReportToAdminFromLobby(string id) { var db = new ZkDataContext(); int idint; Account user = null; if (int.TryParse(id, out idint)) { user = Account.AccountByLobbyID(db, idint); } if (user == null) { user = Account.AccountByName(db, id); } return(View("ReportToAdmin", user)); }
public ActionResult LobbyDetail(string id) { var db = new ZkDataContext(); int idint; Account user = null; if (int.TryParse(id, out idint)) { user = Account.AccountByLobbyID(db, idint); } if (user == null) { user = Account.AccountByName(db, id); } return(View("UserDetail", user)); }
Account UpdateUser(int lobbyID, string name, User user, string hashedPassword, ZkDataContext db = null) { Account acc = null; if (db == null) { db = new ZkDataContext(); } acc = Account.AccountByLobbyID(db, lobbyID); if (acc == null) { acc = new Account(); db.Accounts.InsertOnSubmit(acc); } acc.LobbyID = lobbyID; acc.Name = name; if (!string.IsNullOrEmpty(hashedPassword)) { acc.Password = hashedPassword; } acc.LastLogin = DateTime.UtcNow; if (user != null) // user was online, we can update his data { acc.IsBot = user.IsBot; acc.IsLobbyAdministrator = user.IsAdmin; acc.Country = user.Country; acc.LobbyTimeRank = user.Rank; } db.SubmitAndMergeChanges(); return(acc); }
List <Faction> GetDefendingFactions(AttackOption target) { if (target.OwnerFactionID != null) { return new List <Faction> { factions.Find(x => x.FactionID == target.OwnerFactionID) } } ; return(factions.Where(x => x != AttackingFaction).ToList()); } void JoinPlanetAttack(int targetPlanetId, string userName) { AttackOption attackOption = AttackOptions.Find(x => x.PlanetID == targetPlanetId); if (attackOption != null) { User user; if (tas.ExistingUsers.TryGetValue(userName, out user)) { var db = new ZkDataContext(); Account account = Account.AccountByLobbyID(db, user.LobbyID); if (account != null && account.FactionID == AttackingFaction.FactionID && account.CanPlayerPlanetWars()) { // remove existing user from other options foreach (AttackOption aop in AttackOptions) { aop.Attackers.RemoveAll(x => x == userName); } // add user to this option if (attackOption.Attackers.Count < attackOption.TeamSize) { attackOption.Attackers.Add(user.Name); tas.Say(TasClient.SayPlace.Channel, user.Faction, string.Format("{0} joins attack on {1}", userName, attackOption.Name), true); if (attackOption.Attackers.Count == attackOption.TeamSize) { StartChallenge(attackOption); } else { UpdateLobby(); } } } } } } void JoinPlanetDefense(int targetPlanetID, string userName) { if (Challenge != null && Challenge.PlanetID == targetPlanetID && Challenge.Defenders.Count < Challenge.TeamSize) { User user; if (tas.ExistingUsers.TryGetValue(userName, out user)) { var db = new ZkDataContext(); Account account = Account.AccountByLobbyID(db, user.LobbyID); if (account != null && GetDefendingFactions(Challenge).Any(y => y.FactionID == account.FactionID) && account.CanPlayerPlanetWars()) { if (!Challenge.Defenders.Any(y => y == user.Name)) { Challenge.Defenders.Add(user.Name); tas.Say(TasClient.SayPlace.Channel, user.Faction, string.Format("{0} joins defense of {1}", userName, Challenge.Name), true); if (Challenge.Defenders.Count == Challenge.TeamSize) { AcceptChallenge(); } else { UpdateLobby(); } } } } } } void RecordPlanetwarsLoss(AttackOption option) { if (option.OwnerFactionID != null) { if (option.OwnerFactionID == missedDefenseFactionID) { missedDefenseCount++; } else { missedDefenseCount = 0; missedDefenseFactionID = option.OwnerFactionID.Value; } } var message = string.Format("{0} won because nobody tried to defend", AttackingFaction.Name); foreach (var fac in factions) { tas.Say(TasClient.SayPlace.Channel, fac.Shortcut, message, true); } var text = new StringBuilder(); try { var db = new ZkDataContext(); List <string> playerIds = option.Attackers.Select(x => x).Union(option.Defenders.Select(x => x)).ToList(); PlanetWarsTurnHandler.EndTurn(option.Map, null, db, 0, db.Accounts.Where(x => playerIds.Contains(x.Name) && x.Faction != null).ToList(), text, null, db.Accounts.Where(x => option.Attackers.Contains(x.Name) && x.Faction != null).ToList()); } catch (Exception ex) { Trace.TraceError(ex.ToString()); text.Append(ex); } } void ResetAttackOptions() { AttackOptions.Clear(); AttackerSideChangeTime = DateTime.UtcNow; Challenge = null; ChallengeTime = null; using (var db = new ZkDataContext()) { var gal = db.Galaxies.First(x => x.IsDefault); int cnt = 2; var attacker = db.Factions.Single(x => x.FactionID == AttackingFaction.FactionID); var planets = gal.Planets.Where(x => x.OwnerFactionID != AttackingFaction.FactionID).OrderByDescending(x => x.PlanetFactions.Where(y => y.FactionID == AttackingFaction.FactionID).Sum(y => y.Dropships)).ThenByDescending(x => x.PlanetFactions.Where(y => y.FactionID == AttackingFaction.FactionID).Sum(y => y.Influence)).ToList(); // list of planets by attacker's influence foreach (var planet in planets) { if (planet.CanMatchMakerPlay(attacker)) { // pick only those where you can actually attack atm InternalAddOption(planet); cnt--; } if (cnt == 0) { break; } } if (!AttackOptions.Any(y => y.TeamSize == 2)) { var planet = planets.FirstOrDefault(x => x.TeamSize == 2 && x.CanMatchMakerPlay(attacker)); if (planet != null) { InternalAddOption(planet); } } } UpdateLobby(); tas.Say(TasClient.SayPlace.Channel, AttackingFaction.Shortcut, "It's your turn! Select a planet to attack", true); } void InternalAddOption(Planet planet) { AttackOptions.Add(new AttackOption { PlanetID = planet.PlanetID, Map = planet.Resource.InternalName, OwnerFactionID = planet.OwnerFactionID, Name = planet.Name, TeamSize = planet.TeamSize, }); } void SaveStateToDb() { var db = new ZkDataContext(); Galaxy gal = db.Galaxies.First(x => x.IsDefault); gal.MatchMakerState = JsonConvert.SerializeObject((MatchMakerState)this); gal.AttackerSideCounter = AttackerSideCounter; gal.AttackerSideChangeTime = AttackerSideChangeTime; db.SubmitAndMergeChanges(); } void StartChallenge(AttackOption attackOption) { Challenge = attackOption; ChallengeTime = DateTime.UtcNow; AttackOptions.Clear(); UpdateLobby(); } void TasOnChannelUserAdded(object sender, TasEventArgs args) { string chan = args.ServerParams[0]; string userName = args.ServerParams[1]; Faction faction = factions.FirstOrDefault(x => x.Shortcut == chan); if (faction != null) { var db = new ZkDataContext(); var acc = Account.AccountByName(db, userName); if (acc != null && acc.CanPlayerPlanetWars()) { UpdateLobby(userName); } } } /// <summary> /// Intercept channel messages for attacking/defending /// </summary> /// <param name="sender"></param> /// <param name="args"></param> void TasOnPreviewSaid(object sender, CancelEventArgs <TasSayEventArgs> args) { if (args.Data.Text.StartsWith("!") && (args.Data.Place == TasSayEventArgs.Places.Channel || args.Data.Place == TasSayEventArgs.Places.Normal) && args.Data.Origin == TasSayEventArgs.Origins.Player && args.Data.UserName != GlobalConst.NightwatchName) { int targetPlanetId; if (int.TryParse(args.Data.Text.Substring(1), out targetPlanetId)) { JoinPlanet(args.Data.UserName, targetPlanetId); } } } /// <summary> /// Remove/reduce poll count due to lobby quits /// </summary> void TasOnUserRemoved(object sender, TasEventArgs args) { if (Challenge == null) { if (AttackOptions.Count > 0) { string userName = args.ServerParams[0]; int sumRemoved = 0; foreach (AttackOption aop in AttackOptions) { sumRemoved += aop.Attackers.RemoveAll(x => x == userName); } if (sumRemoved > 0) { UpdateLobby(); } } } else { string userName = args.ServerParams[0]; if (Challenge.Defenders.RemoveAll(x => x == userName) > 0) { UpdateLobby(); } } } void TimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs) { try { if (Challenge == null) { // attack timer if (DateTime.UtcNow > GetAttackDeadline()) { AttackerSideCounter++; ResetAttackOptions(); } } else { // accept timer if (DateTime.UtcNow > GetAcceptDeadline()) { if (Challenge.Defenders.Count >= Challenge.Attackers.Count - 1 && Challenge.Defenders.Count > 0) { AcceptChallenge(); } else { RecordPlanetwarsLoss(Challenge); AttackerSideCounter++; ResetAttackOptions(); } } } } catch (Exception ex) { Trace.TraceError(ex.ToString()); } }
void tas_Said(object sender, TasSayEventArgs e) { if (e.UserName.Contains("Nightwatch")) { return; } if (e.Place == TasSayEventArgs.Places.Normal) { foreach (string command in adminCommands) { if (e.Text.StartsWith("!" + command)) { var db = new ZkDataContext(); var acc = Account.AccountByLobbyID(db, tas.ExistingUsers[e.UserName].LobbyID); if (!(acc.IsZeroKAdmin || acc.IsLobbyAdministrator)) { return; } break; } } if (e.Text.StartsWith("!kick")) { var parts = e.Text.Split(' '); if (!(parts.Length >= 2)) { tas.Say(TasClient.SayPlace.User, e.UserName, "!kick [player] [reason]", false); } else { var player = tas.ExistingUsers.FirstOrDefault(x => x.Key == parts[1]).Key; var reasonParts = ((string[])parts.Clone()).ToList(); reasonParts.RemoveRange(0, 2); string reason = string.Join(" ", reasonParts) ?? ""; if (player != null) { tas.AdminKickFromLobby(player, reason); } else { tas.Say(TasClient.SayPlace.User, e.UserName, "Not a valid player name", false); } } } else if (e.Text.StartsWith("!op")) { var parts = e.Text.Split(' '); if (parts.Length != 3) { tas.Say(TasClient.SayPlace.User, e.UserName, "!op [player] [channel]", false); } else { var player = tas.ExistingUsers.FirstOrDefault(x => x.Key == parts[1]).Key; var channel = parts[2]; if (player != null) { tas.Say(TasClient.SayPlace.User, "ChanServ", string.Format("!op {0} {1}", channel, player), false); tas.Say(TasClient.SayPlace.User, e.UserName, string.Format("DEBUG: !op {0} {1}", channel, player), false); } else { tas.Say(TasClient.SayPlace.User, e.UserName, "Not a valid player name", false); } } } else if (e.Text.StartsWith("!changeaccountpass")) { var parts = e.Text.Split(' '); if (parts.Length != 3) { tas.Say(TasClient.SayPlace.User, e.UserName, "!changeaccountpass [player] [password (plaintext)]", false); } else { var password = PlasmaShared.Utils.HashLobbyPassword(parts[2]); tas.SendRaw(string.Format("CHANGEACCOUNTPASS {0} {1}", parts[1], password)); tas.Say(TasClient.SayPlace.User, e.UserName, string.Format("DEBUG: CHANGEACCOUNTPASS {0} {1}", parts[1], password), false); } } else if (e.Text.StartsWith("!chanserv")) { var command = e.Text.Substring(9).TrimStart(); tas.Say(TasClient.SayPlace.User, "ChanServ", "!" + command, false); } } }
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.SmallTeams || mode == AutohostMode.GameFFA || mode == AutohostMode.Teams || mode == AutohostMode.LowSkill || mode == AutohostMode.HighSkill) { 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.LobbyID == 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.LobbyID == 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 = Account.AccountByLobbyID(db, 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 }); 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; } }
public static PlayerJoinResult AutohostPlayerJoined(BattleContext context, int accountID) { var res = new PlayerJoinResult(); var db = new ZkDataContext(); AutohostMode mode = context.GetMode(); if (mode == AutohostMode.Planetwars) { Planet planet = db.Galaxies.Single(x => x.IsDefault).Planets.SingleOrDefault(x => x.Resource.InternalName == context.Map); if (planet == null) { res.PublicMessage = "Invalid map"; return(res); } Account account = Account.AccountByLobbyID(db, accountID); // accountID is in fact lobbyID if (account != null) { if (account.Level < context.GetConfig().MinLevel) { res.PrivateMessage = string.Format("Sorry, PlanetWars is competive online campaign for experienced players. You need to be at least level {0} to play here. To increase your level, play more games on other hosts or open multiplayer game and play against computer AI bots. You can still spectate this game, however.", context.GetConfig().MinLevel); res.ForceSpec = true; return(res); } /* * if (account.Faction == null) * { * res.PrivateMessage = * string.Format( * "{0} this is competitive PlanetWars campaign server. Join a clan to conquer the galaxy http://zero-k.info/Factions", * account.Name); * return res; * }*/ string owner = ""; if (planet.Account != null) { owner = planet.Account.Name; } string facRoles = string.Join(",", account.AccountRolesByAccountID.Where(x => !x.RoleType.IsClanOnly).Select(x => x.RoleType.Name).ToList()); if (!string.IsNullOrEmpty(facRoles)) { facRoles += " of " + account.Faction.Name + ", "; } string clanRoles = string.Join(",", account.AccountRolesByAccountID.Where(x => x.RoleType.IsClanOnly).Select(x => x.RoleType.Name).ToList()); if (!string.IsNullOrEmpty(clanRoles)) { clanRoles += " of " + account.Clan.ClanName; } res.PublicMessage = string.Format("Greetings {0} {1}{2}, welcome to {3} planet {4} http://zero-k.info/PlanetWars/Planet/{5}", account.Name, facRoles, clanRoles, owner, planet.Name, planet.PlanetID); return(res); } } Account acc = Account.AccountByLobbyID(db, accountID); // accountID is in fact lobbyID if (acc != null) { AutohostConfig config = context.GetConfig(); if (acc.Level < config.MinLevel) { res.PrivateMessage = string.Format("Sorry, you need to be at least level {0} to play here. To increase your level, play more games on other hosts or open multiplayer game and play against computer AI bots. You can still spectate this game, however.", config.MinLevel); res.ForceSpec = true; return(res); } else if (acc.Level > config.MaxLevel) { res.PrivateMessage = string.Format("Sorry, your level must be {0} or lower to play here. Pick on someone your own size! You can still spectate this game, however.", config.MaxLevel); res.ForceSpec = true; return(res); } // FIXME: use 1v1 Elo for 1v1 if (acc.EffectiveElo < config.MinElo) { res.PrivateMessage = string.Format("Sorry, you need to have an Elo rating of at least {0} to play here. Win games against human opponents to raise your Elo. You can still spectate this game, however.", config.MinElo); res.ForceSpec = true; return(res); } else if (acc.EffectiveElo > config.MaxElo) { res.PrivateMessage = string.Format("Sorry, your Elo rating must be {0} or lower to play here. Pick on someone your own size! You can still spectate this game, however.", config.MaxElo); res.ForceSpec = true; return(res); } } return(null); }
public AuthService(TasClient client) { this.client = client; /* * this.client.Input += (s, e) => * { * Console.WriteLine(e.Command +" "+ Utils.Glue(e.Args)); * }; * this.client.Output += (s, e) => * { * Console.WriteLine(e.Data.Key + " " +Utils.Glue(e.Data.Value.Select(x=>x.ToString()).ToArray())); * };*/ this.client.LoginAccepted += (s, e) => { requests.Clear(); client.JoinChannel(ModeratorChannel); client.JoinChannel(Top20Channel); using (var db = new ZkDataContext()) foreach (var fac in db.Factions.Where(x => !x.IsDeleted)) { client.JoinChannel(fac.Shortcut); } }; this.client.TestLoginAccepted += (s, e) => { RequestInfo entry; if (requests.TryGetValue(client.MessageID, out entry)) { entry.CorrectName = e.ServerParams[0]; entry.LobbyID = Convert.ToInt32(e.ServerParams[1]); if (client.ExistingUsers.ContainsKey(entry.CorrectName)) { entry.User = client.ExistingUsers[entry.CorrectName]; } entry.WaitHandle.Set(); } requests.TryRemove(client.MessageID, out entry); }; this.client.UserAdded += (s, e) => { using (var db = new ZkDataContext()) { var acc = Account.AccountByLobbyID(db, e.Data.LobbyID); if (acc != null) { this.client.Extensions.PublishAccountData(acc); if (acc.SpringieLevel > 2 || acc.IsZeroKAdmin) { client.ForceJoinChannel(e.Data.Name, ModeratorChannel); } if (topPlayers.IsTop20(e.Data.LobbyID)) { client.ForceJoinChannel(e.Data.Name, Top20Channel); } if (acc.Clan != null) { client.ForceJoinChannel(e.Data.Name, acc.Clan.GetClanChannel(), acc.Clan.Password); } if (acc.Faction != null && acc.Level >= GlobalConst.FactionChannelMinLevel && acc.CanPlayerPlanetWars()) { client.ForceJoinChannel(e.Data.Name, acc.Faction.Shortcut); } } client.RequestUserIP(e.Data.Name); client.RequestUserID(e.Data.Name); } }; this.client.UserIDRecieved += (sender, args) => { Task.Factory.StartNew(() => { try { using (var db = new ZkDataContext()) { var acc = Account.AccountByName(db, args.Name); var penalty = Punishment.GetActivePunishment(acc != null ? acc.AccountID : 0, null, args.ID, x => x.BanLobby, db); if (penalty != null) { client.AdminKickFromLobby(args.Name, string.Format("Banned until {0} (ID match to {1}), reason: {2}", penalty.BanExpires, penalty.AccountByAccountID.Name, penalty.Reason)); } ; if (acc != null && args.ID != 0) { var entry = acc.AccountUserIDS.FirstOrDefault(x => x.UserID == args.ID); if (entry == null) { entry = new AccountUserID { AccountID = acc.AccountID, UserID = args.ID, FirstLogin = DateTime.UtcNow }; db.AccountUserIDS.InsertOnSubmit(entry); } entry.LoginCount++; entry.LastLogin = DateTime.UtcNow; } Account accAnteep = db.Accounts.FirstOrDefault(x => x.AccountID == 4490); bool isAnteepSmurf = accAnteep.AccountUserIDS.Any(x => x.UserID == args.ID); if (isAnteepSmurf) { client.Say(TasClient.SayPlace.Channel, ModeratorChannel, String.Format("Suspected Anteep smurf: {0} (ID match {1}) {2}", args.Name, args.ID, acc != null ? "http://zero-k.info/Users/Detail/" + acc.AccountID : ""), false); } if (args.ID != 0 && args.ID < 1000) { client.Say(TasClient.SayPlace.Channel, ModeratorChannel, String.Format("Suspected Anteep smurf: {0} (too short userID {1}) {2}", args.Name, args.ID, acc != null ? "http://zero-k.info/Users/Detail/" + acc.AccountID : ""), false); } db.SubmitChanges(); } } catch (Exception ex) { Trace.TraceError("Error getting user ID: {0}", ex); } }); }; this.client.UserIPRecieved += (sender, args) => { Task.Factory.StartNew(() => { try { Account acc = null; using (var db = new ZkDataContext()) { acc = Account.AccountByName(db, args.Name); var penalty = Punishment.GetActivePunishment(acc != null ? acc.AccountID : 0, args.IP, null, x => x.BanLobby, db); if (penalty != null) { client.AdminKickFromLobby(args.Name, string.Format("Banned until {0} (IP match to {1}), reason: {2}", penalty.BanExpires, penalty.AccountByAccountID.Name, penalty.Reason)); } if (acc != null) { var entry = acc.AccountIPS.FirstOrDefault(x => x.IP == args.IP); if (entry == null) { entry = new AccountIP { AccountID = acc.AccountID, IP = args.IP, FirstLogin = DateTime.UtcNow }; db.AccountIPS.InsertOnSubmit(entry); } entry.LoginCount++; entry.LastLogin = DateTime.UtcNow; } db.SubmitChanges(); } try { if (acc == null || !acc.HasVpnException) { if (GlobalConst.VpnCheckEnabled) { // check user IP against http://dnsbl.tornevall.org // does not catch all smurfs // mostly false positives, do not use var reversedIP = string.Join(".", args.IP.Split('.').Reverse().ToArray()); try { var resolved = Dns.GetHostEntry(string.Format("{0}.dnsbl.tornevall.org", reversedIP)).AddressList; if (resolved.Length > 0) { client.Say(TasClient.SayPlace.Channel, ModeratorChannel, String.Format("User {0} {3} has IP {1} on dnsbl.tornevall.org ({2} result/s)", args.Name, args.IP, resolved.Length, acc != null ? "http://zero-k.info/Users/Detail/" + acc.AccountID : ""), false); //client.AdminKickFromLobby(args.Name, // "Connection using proxy or VPN is not allowed! (You can ask for exception). See http://dnsbl.tornevall.org/removal.php to get your IP removed from the blacklist."); } } catch (System.Net.Sockets.SocketException sockEx) { // not in database, do nothing } } using (var db = new ZkDataContext()) { Account accAnteep = db.Accounts.FirstOrDefault(x => x.AccountID == 4490); bool isAnteepSmurf = accAnteep.AccountIPS.Any(x => x.IP == args.IP); if (isAnteepSmurf) { client.Say(TasClient.SayPlace.Channel, ModeratorChannel, String.Format("Suspected Anteep smurf: {0} (IP match {1}) {2}", args.Name, args.IP, acc != null ? "http://zero-k.info/Users/Detail/" + acc.AccountID : ""), false); } } using (ZkDataContext db = new ZkDataContext()) { for (int i = 0; i <= 1; i++) { var whois = new Whois(); var data = whois.QueryByIp(args.IP, i == 1); if (!data.ContainsKey("netname")) { data["netname"] = "UNKNOWN NETNAME"; } if (!data.ContainsKey("org-name")) { data["org-name"] = "UNKNOWN ORG"; } if (!data.ContainsKey("abuse-mailbox")) { data["abuse-mailbox"] = "no mailbox"; } if (!data.ContainsKey("notify")) { data["notify"] = "no notify address"; } if (!data.ContainsKey("role")) { data["role"] = "UNKNOWN ROLE"; } if (!data.ContainsKey("descr")) { data["descr"] = "no description"; } if (!data.ContainsKey("remarks")) { data["remarks"] = "no remarks"; } var blockedCompanies = db.BlockedCompanies.Select(x => x.CompanyName.ToLower()).ToList(); var blockedHosts = db.BlockedHosts.Select(x => x.HostName).ToList(); /*if (acc.Country == "MY") * { * client.Say(TasClient.SayPlace.User, "KingRaptor", String.Format("USER {0}\nnetname: {1}\norgname: {2}\ndescr: {3}\nabuse-mailbox: {4}", * acc.Name, data["netname"], data["org-name"], data["descr"], data["abuse-mailbox"]), false); * }*/ if (blockedHosts.Any(x => data["abuse-mailbox"].Contains(x)) || (blockedHosts.Any(x => data["notify"].Contains(x)))) { client.AdminKickFromLobby(args.Name, "Connection using proxy or VPN is not allowed! (You can ask for exception)"); } foreach (string company in blockedCompanies) { if (data["netname"].ToLower().Contains(company) || data["org-name"].ToLower().Contains(company) || data["descr"].ToLower().Contains(company) || data["role"].ToLower().Contains(company) || data["remarks"].ToLower().Contains(company)) { client.AdminKickFromLobby(args.Name, "Connection using proxy or VPN is not allowed! (You can ask for exception)"); break; } } var hostname = Dns.GetHostEntry(args.IP).HostName; if (blockedHosts.Any(hostname.Contains)) { client.AdminKickFromLobby(args.Name, "Connection using proxy or VPN is not allowed! (You can ask for exception)"); } } } } } catch (System.Net.Sockets.SocketException sockEx) { // do nothing } catch (Exception ex) { Trace.TraceError("VPN check error: {0}", ex); client.Say(TasClient.SayPlace.Channel, ModeratorChannel, ex.ToString(), false); } } catch (Exception ex) { Trace.TraceError("Error getting user IP: {0}", ex); //client.Say(TasClient.SayPlace.User, "KingRaptor", ex.ToString(), false); } }); }; this.client.UserStatusChanged += (s, e) => { var user = client.ExistingUsers[e.ServerParams[0]]; Task.Factory.StartNew(() => { try { using (var db = new ZkDataContext()) UpdateUser(user.LobbyID, user.Name, user, null, db); } catch (Exception ex) { Trace.TraceError(ex.ToString()); } }, TaskCreationOptions.LongRunning); }; this.client.BattleUserJoined += (s, e) => { var battle = client.ExistingBattles[e.BattleID]; var founder = battle.Founder; if (founder.IsSpringieManaged) { try { var user = client.ExistingUsers[e.UserName]; /* obsolete; all major lobbies have multiengine support * if (!user.IsZkLobbyUser && !user.IsNotaLobby && battle.EngineVersion != client.ServerSpringVersion && * battle.EngineVersion != client.ServerSpringVersion + ".0") { * client.Say(TasClient.SayPlace.User, * user.Name, * string.Format( * "ALERT! YOU WILL DESYNC!! You NEED SPRING ENGINE {0} to play here. Simply join the game with Zero-K lobby ( http://zero-k.info/Wiki/Download ) OR get the engine from http://springrts.com/dl/buildbot/default/ OR build it on your Linux: http://springrts.com/wiki/Building_Spring_on_Linux ", * battle.EngineVersion), * false); * } */ using (var db = new ZkDataContext()) { var acc = Account.AccountByLobbyID(db, user.LobbyID); var name = founder.Name.TrimNumbers(); var aconf = db.AutohostConfigs.FirstOrDefault(x => x.Login == name); if (acc != null && user != null && aconf != null && (acc.LastLobbyVersionCheck == null || DateTime.UtcNow.Subtract(acc.LastLobbyVersionCheck.Value).TotalDays > 3) && aconf.AutohostMode != 0) { client.RequestLobbyVersion(user.Name); } /* * if (acc != null) * { * int numIDs = acc.AccountUserIDS != null ? acc.AccountUserIDS.Count : 0; * if (numIDs == 0) client.Say(TasClient.SayPlace.User, "KingRaptor", string.Format("USER {0} joined battle {1}; has {2} userIDs; lobby version {3}", acc.Name, founder.Name, numIDs, acc.LobbyVersion), false); * } * else * client.Say(TasClient.SayPlace.User, "KingRaptor", string.Format("USER {0} joined battle {1}", e.UserName + " (NO ACCOUNT)", founder.Name), false); * * if (acc != null) * { * if (!acc.AccountUserIDS.Any()) * { * string reason = string.Format("Sorry you are using unsupported lobby ({0}), please upgrade or use Zero-K Lobby, Weblobby or SpringLobby", acc.LobbyVersion); * client.Say(TasClient.SayPlace.User, user.Name, reason, false); * client.Say(TasClient.SayPlace.User, founder.Name, string.Format("!kick {0} {1}", acc.LobbyVersion, reason), false); * } * }*/ } } catch (Exception ex) { //client.Say(TasClient.SayPlace.User, "KingRaptor", ex.ToString(), false); Trace.TraceError("Error procesisng battle user joined: {0}", ex); } } }; this.client.TestLoginDenied += (s, e) => { RequestInfo entry; if (requests.TryGetValue(client.MessageID, out entry)) { entry.WaitHandle.Set(); } requests.TryRemove(client.MessageID, out entry); }; this.client.UserLobbyVersionRecieved += (s, e) => { using (var db = new ZkDataContext()) { var acc = Account.AccountByName(db, e.Name); if (acc != null) { acc.LobbyVersion = e.LobbyVersion; acc.LastLobbyVersionCheck = DateTime.UtcNow; db.SubmitAndMergeChanges(); if (!acc.LobbyVersion.StartsWith("ZK")) { // FIXME abma broke this (LobbyVersion is now some huge-ass integer instead) //client.Say(TasClient.SayPlace.User, // e.Name, // string.Format( // "WARNING: You are connected using {0} which is not fully compatible with this host. Please use Zero-K lobby. Download it from http://zero-k.info NOTE: to play all Spring games with Zero-K lobby, untick \"Official games\" on its multiplayer tab. Thank you!", // e.LobbyVersion), // false); } } } }; this.client.BattleFound += (s, e) => { if (e.Data.Founder.IsZkLobbyUser && !e.Data.Founder.IsBot) { client.SetBotMode(e.Data.Founder.Name, true); } }; this.client.ChannelUserAdded += (sender, args) => { try { var channel = args.ServerParams[0]; var user = args.ServerParams[1]; if (channel == ModeratorChannel) { var u = client.ExistingUsers[user]; if (u.SpringieLevel <= 2 && !u.IsZeroKAdmin) { client.ForceLeaveChannel(user, ModeratorChannel); } } else if (channel == Top20Channel) { var u = client.ExistingUsers[user]; if (!topPlayers.IsTop20(u.LobbyID) && u.Name != client.UserName) { client.ForceLeaveChannel(user, Top20Channel); } } else { using (var db = new ZkDataContext()) { var fac = db.Factions.FirstOrDefault(x => x.Shortcut == channel); if (fac != null) { // faction channel var u = client.ExistingUsers[user]; var acc = Account.AccountByLobbyID(db, u.LobbyID); if (acc == null || acc.FactionID != fac.FactionID || acc.Level < GlobalConst.FactionChannelMinLevel) { client.ForceLeaveChannel(user, channel); } } } } } catch (Exception ex) { Trace.TraceError("Error procesisng channel user added: {0}", ex); } }; this.client.ChannelUserRemoved += (sender, args) => { try { var channel = args.ServerParams[0]; var user = args.ServerParams[1]; if (channel == ModeratorChannel) { var u = client.ExistingUsers[user]; if (u.SpringieLevel > 2 || u.IsZeroKAdmin) { client.ForceJoinChannel(user, ModeratorChannel); } } } catch (Exception ex) { Trace.TraceError("Error procesisng channel user added: {0}", ex); } }; }
void tas_Said(object sender, TasSayEventArgs e) { if (e.UserName.Contains("Nightwatch")) { return; } if (e.Place == TasSayEventArgs.Places.Normal) { if (e.Text.StartsWith("!move")) { var db = new ZkDataContext(); var acc = Account.AccountByLobbyID(db, tas.ExistingUsers[e.UserName].LobbyID); if (acc.IsZeroKAdmin || acc.IsLobbyAdministrator) { var parts = e.Text.Split(' '); if (parts.Length != 3) { tas.Say(TasClient.SayPlace.User, e.UserName, "!move [from] [to]", false); } else { var from = tas.ExistingBattles.Values.FirstOrDefault(x => x.Founder.Name == parts[1]); var to = tas.ExistingBattles.Values.FirstOrDefault(x => x.Founder.Name == parts[2]); if (from != null && to != null) { foreach (var b in from.Users) { if (!b.LobbyUser.IsInGame && b.Name != from.Founder.Name) { tas.ForceJoinBattle(b.Name, to.BattleID); } } } else { tas.Say(TasClient.SayPlace.User, e.UserName, "Not a valid battle host name", false); } } } } // split players evenly into two games by median elo -> expand to specify proportion to shunt? // TODO: split players and specs separately else if (e.Text.StartsWith("!splitplayers")) { var db = new ZkDataContext(); var acc = Account.AccountByLobbyID(db, tas.ExistingUsers[e.UserName].LobbyID); if (acc.IsZeroKAdmin || acc.IsLobbyAdministrator) { var parts = e.Text.Split(' '); if (parts.Length != 3) { tas.Say(TasClient.SayPlace.User, e.UserName, "!splitplayers [from] [to]", false); } else { var from = tas.ExistingBattles.Values.FirstOrDefault(x => x.Founder.Name == parts[1]); var to = tas.ExistingBattles.Values.FirstOrDefault(x => x.Founder.Name == parts[2]); if (from != null && to != null) { var list = from.Users.Where(x => !x.LobbyUser.IsInGame && x.Name != from.Founder.Name && !x.IsSpectator).OrderBy(x => x.LobbyUser.EffectiveElo); var toMove = list.Take(list.Count() / 2); foreach (var b in toMove) { tas.ForceJoinBattle(b.Name, to.BattleID); } } else { tas.Say(TasClient.SayPlace.User, e.UserName, "Not a valid battle host name", false); } } } } } }