private void rdoBalanceCH_CheckedChanged(object sender, EventArgs e) { if (rdoBalanceCH.Checked) { CurrentBalanceMode = BalanceMode.OppositeClasses; } }
private void rdoBalanceBoth_CheckedChanged(object sender, EventArgs e) { if (rdoBalanceBoth.Checked) { CurrentBalanceMode = BalanceMode.Both; } }
private void rdoBalanceCC_CheckedChanged(object sender, EventArgs e) { if (rdoBalanceCC.Checked) { CurrentBalanceMode = BalanceMode.SameClasses; } }
//Interface function to comply with LegacyBalance public static BalanceTeamsResult BalanceInterface(int teamCount, BalanceMode mode, LobbyHostingContext b, params List <Account>[] unmovablePlayers) { if (b.Players.Where(y => !y.IsSpectator).Count() > 38) // dont try doing million+ iterations (arbitrarily chosen cap) { Trace.TraceWarning("PartitionBalance called with too many players: " + b.Players.Where(y => !y.IsSpectator).Count()); return(new Balancer().LegacyBalance(teamCount, mode, b, unmovablePlayers)); } if (teamCount != 2) { Trace.TraceWarning("PartitionBalance called with invalid number of teams: " + teamCount); return(new Balancer().LegacyBalance(teamCount, mode, b, unmovablePlayers)); } if (unmovablePlayers.Length > 0) { Trace.TraceWarning("PartitionBalance called with too many unmovable players: " + unmovablePlayers.Length); return(new Balancer().LegacyBalance(teamCount, mode, b, unmovablePlayers)); } if (mode == BalanceMode.FactionWise) { Trace.TraceWarning("PartitionBalance called with FactionWise balance mode, which is unsupported"); return(new Balancer().LegacyBalance(teamCount, mode, b, unmovablePlayers)); } try { if (b.IsMatchMakerGame) { mode = BalanceMode.Party; } BalanceTeamsResult ret = new BalanceTeamsResult(); ret.CanStart = true; ret.Players = b.Players.ToList(); ret.Bots = b.Bots.ToList(); List <PlayerItem> players = new List <PlayerItem>(); using (var db = new ZkDataContext()) { var nonSpecList = b.Players.Where(y => !y.IsSpectator).Select(y => (int?)y.LobbyID).ToList(); var accs = db.Accounts.Where(x => nonSpecList.Contains(x.AccountID)).ToList(); if (accs.Count < 1) { ret.CanStart = false; return(ret); } players = b.Players.Where(y => !y.IsSpectator).Select(x => new PlayerItem(x.LobbyID, accs.First(a => a.AccountID == x.LobbyID).GetRating(b.ApplicableRating).Elo, x.Clan, x.PartyID)).ToList(); } var dualResult = Balance(mode, players); dualResult.Players.ForEach(r => ret.Players.Where(x => x.LobbyID == r.LobbyID).ForEach(x => x.AllyID = r.AllyID)); ret.Message = dualResult.Message; return(ret); } catch (Exception ex) { Trace.TraceWarning("PartitionBalance encountered an error: " + ex); return(new Balancer().LegacyBalance(teamCount, mode, b, unmovablePlayers)); } }
/// <summary> /// Initializes a new instance of the OperatorParamsDto class. /// </summary> /// <param name="transactionOfflineMode">Possible values include: /// 'Allow', 'Forbid'</param> /// <param name="balanceMode">Possible values include: 'OnlineBalance', /// 'OfflineBalance'</param> public OperatorParamsDto(int operatorId, int currencyId, TransactionOfflineMode transactionOfflineMode, BalanceMode balanceMode, string operatorName = default(string), string languageCode = default(string), string timezoneId = default(string)) { OperatorId = operatorId; OperatorName = operatorName; CurrencyId = currencyId; LanguageCode = languageCode; TimezoneId = timezoneId; TransactionOfflineMode = transactionOfflineMode; BalanceMode = balanceMode; CustomInit(); }
internal static string ToSerializedValue(this BalanceMode value) { switch (value) { case BalanceMode.OnlineBalance: return("OnlineBalance"); case BalanceMode.OfflineBalance: return("OfflineBalance"); } return(null); }
/// <summary> /// Default constructor. /// </summary> /// <param name="sysSettings">Reference to system settings.</param> /// <param name="relayMode">Relay mode.</param> /// <param name="smartHostBalanceMode">Specifies how smart hosts will balance.</param> /// <param name="smartHosts">Smart hosts.</param> /// <param name="idleTimeout">Session idle timeout seconds.</param> /// <param name="maxConnections">Maximum conncurent conncetions.</param> /// <param name="maxConnectionsPerIP">Maximum conncurent conncetions to one IP address.</param> /// <param name="relayInterval">Relay messages interval seconds.</param> /// <param name="relayRetryInterval">Relay retry messages interval seconds.</param> /// <param name="undeliveredWarning">Specifies after how many minutes delayed delivery message is sent.</param> /// <param name="undelivered">Specifies after how many hours undelivered notification message is sent.</param> /// <param name="storeUndelivered">Specifies if undelivered messages are stored to "Undelivered" folder in mail store.</param> /// <param name="bindings">Specifies SMTP listening info.</param> internal Relay_Settings(System_Settings sysSettings,Relay_Mode relayMode,BalanceMode smartHostBalanceMode,Relay_SmartHost[] smartHosts,int idleTimeout,int maxConnections,int maxConnectionsPerIP,int relayInterval,int relayRetryInterval,int undeliveredWarning,int undelivered,bool storeUndelivered,IPBindInfo[] bindings) { m_pSysSettings = sysSettings; m_RelayMode = relayMode; m_SmartHostsBalanceMode = smartHostBalanceMode; m_pSmartHosts = smartHosts; m_IdleTimeout = idleTimeout; m_MaxConnections = maxConnections; m_MaxConnectionsPerIP = maxConnectionsPerIP; m_RelayInterval = relayInterval; m_RelayRetryInterval = relayRetryInterval; m_SendUndelWaringAfter = undeliveredWarning; m_SendUndeliveredAfter = undelivered; m_StoreUndeliveredMsgs = storeUndelivered; m_pBinds = bindings; }
/// <summary> /// Default constructor. /// </summary> /// <param name="sysSettings">Reference to system settings.</param> /// <param name="relayMode">Relay mode.</param> /// <param name="smartHostBalanceMode">Specifies how smart hosts will balance.</param> /// <param name="smartHosts">Smart hosts.</param> /// <param name="idleTimeout">Session idle timeout seconds.</param> /// <param name="maxConnections">Maximum conncurent conncetions.</param> /// <param name="maxConnectionsPerIP">Maximum conncurent conncetions to one IP address.</param> /// <param name="relayInterval">Relay messages interval seconds.</param> /// <param name="relayRetryInterval">Relay retry messages interval seconds.</param> /// <param name="undeliveredWarning">Specifies after how many minutes delayed delivery message is sent.</param> /// <param name="undelivered">Specifies after how many hours undelivered notification message is sent.</param> /// <param name="storeUndelivered">Specifies if undelivered messages are stored to "Undelivered" folder in mail store.</param> /// <param name="bindings">Specifies SMTP listening info.</param> internal Relay_Settings(System_Settings sysSettings, Relay_Mode relayMode, BalanceMode smartHostBalanceMode, Relay_SmartHost[] smartHosts, int idleTimeout, int maxConnections, int maxConnectionsPerIP, int relayInterval, int relayRetryInterval, int undeliveredWarning, int undelivered, bool storeUndelivered, IPBindInfo[] bindings) { m_pSysSettings = sysSettings; m_RelayMode = relayMode; m_SmartHostsBalanceMode = smartHostBalanceMode; m_pSmartHosts = smartHosts; m_IdleTimeout = idleTimeout; m_MaxConnections = maxConnections; m_MaxConnectionsPerIP = maxConnectionsPerIP; m_RelayInterval = relayInterval; m_RelayRetryInterval = relayRetryInterval; m_SendUndelWaringAfter = undeliveredWarning; m_SendUndeliveredAfter = undelivered; m_StoreUndeliveredMsgs = storeUndelivered; m_pBinds = bindings; }
BalanceTeamsResult LegacyBalance(int teamCount, BalanceMode mode, BattleContext b, params List <Account>[] unmovablePlayers) { var ret = new BalanceTeamsResult(); try { ret.CanStart = true; ret.Players = b.Players.ToList(); var db = new ZkDataContext(); var nonSpecList = b.Players.Where(y => !y.IsSpectator).Select(y => (int?)y.LobbyID).ToList(); var accs = db.Accounts.Where(x => nonSpecList.Contains(x.AccountID)).ToList(); if (accs.Count < 1) { ret.CanStart = false; return(ret); } if (teamCount < 1) { teamCount = 1; } if (teamCount > accs.Count) { teamCount = accs.Count; } if (teamCount == 1) { foreach (var p in ret.Players) { p.AllyID = 0; } return(ret); } maxTeamSize = (int)Math.Ceiling(accs.Count / (double)teamCount); teams.Clear(); for (var i = 0; i < teamCount; i++) { var team = new BalanceTeam(); teams.Add(team); if (unmovablePlayers != null && unmovablePlayers.Length > i) { var unmovables = unmovablePlayers[i]; team.AddItem(new BalanceItem(unmovablePlayers[i].ToArray()) { CanBeMoved = false }); accs.RemoveAll(x => unmovables.Any(y => y.AccountID == x.AccountID)); } } balanceItems = new List <BalanceItem>(); if (mode == BalanceMode.ClanWise) { var clanGroups = accs.GroupBy(x => x.ClanID ?? x.AccountID).ToList(); if (teamCount > clanGroups.Count() || clanGroups.Any(x => x.Count() > maxTeamSize)) { mode = BalanceMode.Normal; } else { balanceItems.AddRange(clanGroups.Select(x => new BalanceItem(x.ToArray()))); } } if (mode == BalanceMode.FactionWise) { balanceItems.Clear(); var factionGroups = accs.GroupBy(x => x.FactionID ?? x.AccountID).ToList(); balanceItems.AddRange(factionGroups.Select(x => new BalanceItem(x.ToArray()))); } if (mode == BalanceMode.Normal) { balanceItems.Clear(); balanceItems.AddRange(accs.Select(x => new BalanceItem(x))); } var sw = new Stopwatch(); sw.Start(); RecursiveBalance(0); sw.Stop(); if (bestTeams == null) { var fallback = new Balancer().LegacyBalance(teamCount, BalanceMode.ClanWise, b, null); fallback.Message += "\nWarning: STANDARD TEAM BALANCE USED, PlanetWars not possible with those teams, too many from one faction"; return(fallback); } var minSize = bestTeams.Min(x => x.Count); var maxSize = bestTeams.Max(x => x.Count); var sizesWrong = maxSize / (double)minSize > MaxTeamSizeDifferenceRatio; // cbalance failed, rebalance using normal if (mode == BalanceMode.ClanWise && (bestTeams == null || GetTeamsDifference(bestTeams) > MaxCbalanceDifference || sizesWrong)) { return(new Balancer().LegacyBalance(teamCount, BalanceMode.Normal, b, unmovablePlayers)); } // cbalance failed, rebalance using normal if (sizesWrong && mode == BalanceMode.FactionWise) { var fallback = new Balancer().LegacyBalance(teamCount, BalanceMode.ClanWise, b, null); fallback.Message += "\nWarning: STANDARD TEAM BALANCE USED, PlanetWars not possible with those teams, too many from one faction"; return(fallback); // fallback standard balance if PW balance fails /*ret.CanStart = false; * ret.Message = string.Format("Failed to balance - too many people from same faction"); * return ret;*/ } if (unmovablePlayers != null && unmovablePlayers.Length > 0) { var minElo = bestTeams.Min(x => x.AvgElo); var maxElo = bestTeams.Max(x => x.AvgElo); if (maxElo - minElo > GlobalConst.MaxPwEloDifference) { var fallback = new Balancer().LegacyBalance(teamCount, BalanceMode.ClanWise, b, null); fallback.Message += "\nWarning: STANDARD TEAM BALANCE USED, PlanetWars not possible with those teams, too many from one faction"; return(fallback); // fallback standard balance if PW balance fails /* * ret.CanStart = false; * ret.Message = string.Format("Team difference is too big - win chance {0}% - spectate some or wait for more people", * Utils.GetWinChancePercent(maxElo - minElo)); * return ret;*/ } } if (bestTeams == null) { ret.CanStart = false; ret.Message = string.Format( "Failed to balance {0} - too many people from same clan or faction (in teams game you can try !random and !forcestart)"); return(ret); } else { if (unmovablePlayers == null || unmovablePlayers.Length == 0) { bestTeams = bestTeams.Shuffle(); // permute when not unmovable players present } var text = "( "; var lastTeamElo = 0.0; var allyNum = 0; foreach (var team in bestTeams) { if (allyNum > 0) { text += " : "; } text += string.Format("{0}", (allyNum + 1)); if (allyNum > 0) { text += string.Format("={0}%)", Utils.GetWinChancePercent(lastTeamElo - team.AvgElo)); } lastTeamElo = team.AvgElo; foreach (var u in team.Items.SelectMany(x => x.LobbyId)) { ret.Players.Single(x => x.LobbyID == u).AllyID = allyNum; } allyNum++; } text += ")"; ret.Message = String.Format("{0} players balanced {2} to {1} teams {3}. {4} combinations checked, spent {5}ms of CPU time", bestTeams.Sum(x => x.Count), teamCount, mode, text, iterationsChecked, sw.ElapsedMilliseconds); } } catch (Exception ex) { Trace.TraceError(ex.ToString()); ret.Message = ex.ToString(); ret.CanStart = false; } return(ret); }
//Balances N players in O(2^(n/2)) //Algorithm described in http://web.cecs.pdx.edu/~bart/cs510ai/papers/korf-ckk.pdf Section 2.2 public static DualBalanceResult Balance(BalanceMode mode, ICollection <PlayerItem> players) { List <PlayerItem> unmodifiedPlayers = players.ToList(); List <List <int> > playerGroups = new List <List <int> >(); List <double> groupSkill = new List <double>(); players.ForEach(x => x.Elo += 1e6); //Purple for everyone, this assures that both teams get an equal number of players if (players.Count % 2 != 0) { //Pad teams to an even number players.Add(new PlayerItem(-1, players.Average(x => x.Elo), null, null)); } int maxTeamSize = players.Count / 2; if (mode == BalanceMode.Party) { var partyGroups = players.GroupBy(x => x.Party ?? x.Account).ToList(); if (2 > partyGroups.Count() || partyGroups.Any(x => x.Count() > maxTeamSize)) { //Party too big, fall through mode = BalanceMode.Normal; } else { playerGroups = partyGroups.Select(x => x.Select(p => p.Account).ToList()).ToList(); groupSkill = partyGroups.Select(x => x.Sum(g => g.Elo)).ToList(); } } if (mode == BalanceMode.ClanWise) { var clanGroups = players.GroupBy(x => x.Party ?? x.Clan ?? x.Account).ToList(); if (2 > clanGroups.Count() || clanGroups.Any(x => x.Count() > maxTeamSize)) { //Clan or party too big, fall through mode = BalanceMode.Normal; } else { playerGroups = clanGroups.Select(x => x.Select(p => p.Account).ToList()).ToList(); groupSkill = clanGroups.Select(x => x.Sum(g => g.Elo)).ToList(); } } if (mode == BalanceMode.Normal) { playerGroups = players.Select(x => new List <int>() { x.Account }).ToList(); groupSkill = players.Select(x => x.Elo).ToList(); } //Find optimal partitioning var sw = new Stopwatch(); sw.Start(); double sum = groupSkill.Sum(); maxTeamSize = playerGroups.Count / 2; List <Subset> firstList = generateAllSubsets(groupSkill.Where((x, i) => i < maxTeamSize).ToList()); List <Subset> secondList = generateAllSubsets(groupSkill.Where((x, i) => i >= maxTeamSize).ToList()); //Any partition can be represented as a combination of a partition of the first and the second half //There are N^2 possibilities, but we only look at the N ones where the sum of both is as close to the target as possible firstList.Sort(); secondList.Sort(); int a = 0; //Iterates first list in ascending order int b = secondList.Count - 1; //Iterates second list in descending order double bestDiff = Double.MaxValue; UInt64 bestAssignment = 0; //Each bit from right to left represents whether the ith player is in the first or second team while (a < firstList.Count && b >= 0) { while (b >= 0 && firstList[a].Sum + secondList[b].Sum > sum / 2) { b--; } if (b >= 0 && sum - 2 * (firstList[a].Sum + secondList[b].Sum) < bestDiff) { bestDiff = sum - 2 * (firstList[a].Sum + secondList[b].Sum); bestAssignment = firstList[a].Elements | (secondList[b].Elements << (maxTeamSize)); } a++; } sw.Stop(); //Return results if (mode == BalanceMode.ClanWise && (bestDiff > MaxCbalanceDifference)) { //Not very balanced, fall back return(Balance(BalanceMode.Normal, unmodifiedPlayers)); } DualBalanceResult ret = new DualBalanceResult() { EloDifference = 2 * bestDiff / players.Count, Players = players.Where(p => p.Account > 0).Select(x => new PlayerTeam() { LobbyID = x.Account }).ToList() }; int j = 0; while (j < playerGroups.Count) { //iterate through assignment bit by bit if ((bestAssignment & 0x1) == 0) { ret.Players.Where(p => playerGroups[j].Contains(p.LobbyID)).ForEach(x => x.AllyID = 0); } else { ret.Players.Where(p => playerGroups[j].Contains(p.LobbyID)).ForEach(x => x.AllyID = 1); } j++; bestAssignment >>= 1; } //Make that nice message var text = string.Format("( ( 1={0}%) : 2={1}%))", (int)Math.Round((1.0 / (1.0 + Math.Pow(10, -ret.EloDifference / 400.0))) * 100.0), (int)Math.Round((1.0 / (1.0 + Math.Pow(10, ret.EloDifference / 400.0))) * 100.0)); ret.LowestWinChance = 1.0 / (1.0 + Math.Pow(10, ret.EloDifference / 400.0)); ret.Message = string.Format( "{0} players balanced {2} to {1} teams {3}. {4} combinations checked, spent {5}ms of CPU time", unmodifiedPlayers.Count, 2, mode, text, (1UL << maxTeamSize), sw.ElapsedMilliseconds); return(ret); }
/// <summary> /// The function that actually moves players arounds /// </summary> /// <param name="teamCount"></param> /// <param name="mode"></param> /// <param name="b"></param> /// <param name="unmovablePlayers"></param> /// <returns></returns> BalanceTeamsResult LegacyBalance(int teamCount, BalanceMode mode, LobbyHostingContext b, params List<Account>[] unmovablePlayers) { var ret = new BalanceTeamsResult(); if (b.IsMatchMakerGame) mode = BalanceMode.Party; // override, for matchmaker mode is always party try { ret.CanStart = true; ret.Players = b.Players.ToList(); var db = new ZkDataContext(); var nonSpecList = b.Players.Where(y => !y.IsSpectator).Select(y => (int?)y.LobbyID).ToList(); var accs = db.Accounts.Where(x => nonSpecList.Contains(x.AccountID)).ToList(); if (accs.Count < 1) { ret.CanStart = false; return ret; } if (teamCount < 1) teamCount = 1; if (teamCount > accs.Count) teamCount = accs.Count; if (teamCount == 1) { foreach (var p in ret.Players) p.AllyID = 0; return ret; } maxTeamSize = (int)Math.Ceiling(accs.Count / (double)teamCount); teams.Clear(); for (var i = 0; i < teamCount; i++) { var team = new BalanceTeam(); teams.Add(team); if (unmovablePlayers != null && unmovablePlayers.Length > i) { var unmovables = unmovablePlayers[i]; team.AddItem(new BalanceItem(b.IsMatchMakerGame, unmovablePlayers[i].ToArray()) { CanBeMoved = false }); accs.RemoveAll(x => unmovables.Any(y => y.AccountID == x.AccountID)); } } balanceItems = new List<BalanceItem>(); if (mode == BalanceMode.Party) { var clanGroups = accs.GroupBy(x => b.Players.First(p => p.Name == x.Name).PartyID ?? x.AccountID).ToList(); if (teamCount > clanGroups.Count() || clanGroups.Any(x => x.Count() > maxTeamSize)) mode = BalanceMode.Normal; else balanceItems.AddRange(clanGroups.Select(x => new BalanceItem(b.IsMatchMakerGame, x.ToArray()))); } if (mode == BalanceMode.ClanWise) { var clanGroups = accs.GroupBy(x => b.Players.First(p => p.Name == x.Name).PartyID ?? x.ClanID ?? x.AccountID).ToList(); if (teamCount > clanGroups.Count() || clanGroups.Any(x => x.Count() > maxTeamSize)) mode = BalanceMode.Normal; else balanceItems.AddRange(clanGroups.Select(x => new BalanceItem(b.IsMatchMakerGame, x.ToArray()))); } if (mode == BalanceMode.FactionWise) { balanceItems.Clear(); var factionGroups = accs.GroupBy(x => x.FactionID ?? x.AccountID).ToList(); balanceItems.AddRange(factionGroups.Select(x => new BalanceItem(b.IsMatchMakerGame, x.ToArray()))); } if (mode == BalanceMode.Normal) { balanceItems.Clear(); balanceItems.AddRange(accs.Select(x => new BalanceItem(b.IsMatchMakerGame, x))); } var sw = new Stopwatch(); sw.Start(); RecursiveBalance(0); sw.Stop(); if (bestTeams == null) { var fallback = new Balancer().LegacyBalance(teamCount, BalanceMode.ClanWise, b, null); fallback.Message += "\nWarning: STANDARD TEAM BALANCE USED, PlanetWars not possible with those teams, too many from one faction"; return fallback; } var minSize = bestTeams.Min(x => x.Count); var maxSize = bestTeams.Max(x => x.Count); var sizesWrong = maxSize / (double)minSize > MaxTeamSizeDifferenceRatio; // cbalance failed, rebalance using normal if (mode == BalanceMode.ClanWise && (bestTeams == null || GetTeamsDifference(bestTeams) > MaxCbalanceDifference || sizesWrong)) return new Balancer().LegacyBalance(teamCount, BalanceMode.Normal, b, unmovablePlayers); // cbalance failed, rebalance using normal if (sizesWrong && mode == BalanceMode.FactionWise) { var fallback = new Balancer().LegacyBalance(teamCount, BalanceMode.ClanWise, b, null); fallback.Message += "\nWarning: STANDARD TEAM BALANCE USED, PlanetWars not possible with those teams, too many from one faction"; return fallback; // fallback standard balance if PW balance fails /*ret.CanStart = false; ret.Message = string.Format("Failed to balance - too many people from same faction"); return ret;*/ } if (unmovablePlayers != null && unmovablePlayers.Length > 0) { var minElo = bestTeams.Min(x => x.AvgElo); var maxElo = bestTeams.Max(x => x.AvgElo); if (maxElo - minElo > GlobalConst.MaxPwEloDifference) { var fallback = new Balancer().LegacyBalance(teamCount, BalanceMode.ClanWise, b, null); fallback.Message += "\nWarning: STANDARD TEAM BALANCE USED, PlanetWars not possible with those teams, too many from one faction"; return fallback; // fallback standard balance if PW balance fails /* ret.CanStart = false; ret.Message = string.Format("Team difference is too big - win chance {0}% - spectate some or wait for more people", Utils.GetWinChancePercent(maxElo - minElo)); return ret;*/ } } if (bestTeams == null) { ret.CanStart = false; ret.Message = string.Format( "Failed to balance {0} - too many people from same clan or faction (in teams game you can try !random and !forcestart)"); return ret; } if (unmovablePlayers == null || unmovablePlayers.Length == 0) bestTeams = bestTeams.Shuffle(); // permute when not unmovable players present var text = "( "; var lastTeamElo = 0.0; var allyNum = 0; foreach (var team in bestTeams) { if (allyNum > 0) text += " : "; text += string.Format("{0}", (allyNum + 1)); if (allyNum > 0) text += string.Format("={0}%)", Utils.GetWinChancePercent(lastTeamElo - team.AvgElo)); lastTeamElo = team.AvgElo; foreach (var u in team.Items.SelectMany(x => x.LobbyId)) ret.Players.Single(x => x.LobbyID == u).AllyID = allyNum; allyNum++; } text += ")"; ret.Message = string.Format( "{0} players balanced {2} to {1} teams {3}. {4} combinations checked, spent {5}ms of CPU time", bestTeams.Sum(x => x.Count), teamCount, mode, text, iterationsChecked, sw.ElapsedMilliseconds); } catch (Exception ex) { Trace.TraceError(ex.ToString()); ret.Message = ex.ToString(); ret.CanStart = false; } return ret; }
//public static bool UpdateBalance(CrmDbContext db, BankAccount account, double amount, BalanceMode balanceMode = BalanceMode.Increment) //{ // try // { // switch (balanceMode) // { // case BalanceMode.Increment: // account.Balance += amount; // break; // case BalanceMode.Decrement: // account.Balance -= amount; // break; // } // db.Entry(account).State = EntityState.Modified; // return db.SaveChanges() > 0; // } // catch (Exception ex) // { // return false; // } //} public static bool UpdateBalance(this CrmDbContext db, BankAccount account, double amount, BalanceMode balanceMode = BalanceMode.Increment) { try { switch (balanceMode) { case BalanceMode.Increment: account.Balance += amount; break; case BalanceMode.Decrement: account.Balance -= amount; break; } db.Entry(account).State = EntityState.Modified; return(db.SaveChanges() > 0); } catch (Exception ex) { return(false); } }