Skip to content

Commit

Permalink
Merge pull request #2682 from Legomenon-gh/mm-veto
Browse files Browse the repository at this point in the history
Simple implementation of MM map veto
  • Loading branch information
DeinFreund authored Jun 18, 2020
2 parents 93b84d3 + 13a764a commit dacb3e4
Show file tree
Hide file tree
Showing 18 changed files with 485 additions and 9 deletions.
28 changes: 28 additions & 0 deletions Shared/PlasmaShared/MapBanConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Collections.Generic;

namespace ZkData
{
public class MapBanConfig
{
private static Dictionary<int, int> BansPerPlayerByGameSize = new Dictionary<int, int>() {
// 6 bans per player in a 2 player game, 3 bans per player in a 4 or 6 player game
{ 2, 6 },
{ 4, 3 },
{ 6, 3 },
{ 8, 2 },
{ 10, 1 },
{ 12, 1 }
};

public static int GetPlayerBanCount(int gameSize)
{
int value;
return BansPerPlayerByGameSize.TryGetValue(gameSize, out value) ? value : 1;
}

public static int GetMaxBanCount()
{
return GetPlayerBanCount(2);
}
}
}
1 change: 1 addition & 0 deletions Shared/PlasmaShared/PlasmaShared.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
<ItemGroup>
<Compile Include="AuthTools.cs" />
<Compile Include="ChangeEventArgs.cs" />
<Compile Include="MapBanConfig.cs" />
<Compile Include="CommandJsonSerializer.cs" />
<Compile Include="Crc.cs" />
<Compile Include="Diagrams\Diagram.cs" />
Expand Down
21 changes: 16 additions & 5 deletions Zero-K.info/Controllers/AutocompleteController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public ActionResult Index(string term) {
ret.AddRange(CompleteUsers(term, null, db));
ret.AddRange(CompleteThreads(term, null, db));
ret.AddRange(CompleteMissions(term, db));
ret.AddRange(CompleteMaps(term, db));
ret.AddRange(CompleteMaps(term, null, db));
}

return Json(ret, JsonRequestBehavior.AllowGet);
Expand All @@ -40,7 +40,12 @@ public ActionResult UsersNoLink(string term, int? threadID)

public ActionResult Maps(string term)
{
return Json(CompleteMaps(term, new ZkDataContext()), JsonRequestBehavior.AllowGet);
return Json(CompleteMaps(term, null, new ZkDataContext()), JsonRequestBehavior.AllowGet);
}

public ActionResult MatchMakerMaps(string term)
{
return Json(CompleteMaps(term, MapSupportLevel.MatchMaker, new ZkDataContext()), JsonRequestBehavior.AllowGet);
}

public ActionResult Missions(string term)
Expand Down Expand Up @@ -108,11 +113,17 @@ IEnumerable<AutocompleteItem> CompleteThreads(string term, int? categoryID, ZkDa
});
}

IEnumerable<AutocompleteItem> CompleteMaps(string term, ZkDataContext db) {
IEnumerable<AutocompleteItem> CompleteMaps(string term, MapSupportLevel? mapSupportLevel, ZkDataContext db) {
if (string.IsNullOrEmpty(term)) return new List<AutocompleteItem>();
return
db.Resources.Where(x => x.InternalName.Contains(term) && x.TypeID == ResourceType.Map)
var maps = db.Resources.AsQueryable();
if (mapSupportLevel != null)
{
maps = maps.Where(x => x.MapSupportLevel == mapSupportLevel);
}

return maps.Where(x => x.InternalName.Contains(term) && x.TypeID == ResourceType.Map)
.OrderByDescending(x => x.MapSupportLevel)
.ThenBy(x => x.InternalName)
.Take(autocompleteCount)
.ToList()
.Select(
Expand Down
91 changes: 91 additions & 0 deletions Zero-K.info/Controllers/MapBansController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using ZkData;

namespace ZeroKWeb.Controllers
{
public class MapBansController : Controller
{
[Auth]
/// <summary>
/// Returns current user's map bans and allows editing them.
/// </summary>
///
public ActionResult Index()
{
var db = new ZkDataContext();
List<AccountMapBan> bans = db.AccountMapBans
.Where(x => x.AccountID == Global.AccountID)
.OrderBy(x => x.Rank)
.ToList();

var viewModel = new MapBansViewModel
{
accountBans = bans,
maxBans = MapBanConfig.GetMaxBanCount()
};

return View("MapBansIndex", viewModel);
}

[Auth]
/// <summary>
/// Overrides current user's map bans.
/// </summary>
///

public ActionResult Update(List<String> mapName)
{
if (mapName == null) return Content("No input given");

// Duplicates would not break anything but they're probably a sign of user error so validate against them.
var hasDuplicate = mapName.Where(x => x != "").GroupBy(x => x).Any(g => g.Count() > 1);
if (hasDuplicate)
{
return Content("The same map cannot be banned multiple times.");
}

// TODO: It would be nicer to use IDs instead of the map names to drive this
// Fetch the actual resources to sanity check user input and silently ignore
// any input that does not actually exist.
// Filter against current matchmaker to remove any existing bans for a map
// that has been removed from the MM pool.
var db = new ZkDataContext();
var mapIDs = db.Resources
.Where(x => x.TypeID == ResourceType.Map && mapName.Contains(x.InternalName) && x.MapSupportLevel == MapSupportLevel.MatchMaker)
.ToList();

// Ban rank matters so sort the maps according to the user provided ordering
mapIDs = mapIDs.OrderBy(x => mapName.IndexOf(x.InternalName)).ToList();

var newMapBans = new List<AccountMapBan>();
for (int i = 0; i < mapIDs.Count; i++)
{
var ban = new AccountMapBan
{
Rank = i + 1,
AccountID = Global.AccountID,
BannedMapResourceID = mapIDs[i].ResourceID
};
newMapBans.Add(ban);
}

// Since users may only have a few bans and will not often update them,
// recreate them from scratch on submission. This shortcut simplifies handling
// partial updates that modify a ban's rank and handling multiple bans for the same map.
db.AccountMapBans.RemoveRange(db.AccountMapBans.Where(x => x.AccountID == Global.AccountID));
db.AccountMapBans.InsertAllOnSubmit(newMapBans);
db.SaveChanges();

return RedirectToAction("Index");
}
}

public class MapBansViewModel
{
public List<AccountMapBan> accountBans;
public int maxBans;
}
}
26 changes: 26 additions & 0 deletions Zero-K.info/Views/MapBans/MapBansIndex.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@using ZeroKWeb.Controllers
@model MapBansViewModel
@{
Page.Title = "Map bans";
}

<h2>Map bans</h2>

<p>You may select up to @(Model.maxBans) maps to ban from your matchmaking games.
Remove an existing ban by clearing the box and hitting Save. </p>

<p> For 1v1 games, all your bans will be used.
For team games, your first few unique bans will be used depending on the size of the game. </p>

<form action="@Url.Action("Update")" method="post">
@for (int i = 0; i < Model.maxBans; i++)
{
String mapName = i < Model.accountBans.Count ? Model.accountBans[i].Resource.InternalName : null;

<div style="margin-bottom:10px">
<span style="padding-right:10px;">Ban @(i+1):</span>
<span>@Html.TextBox("mapName", mapName, new { data_autocomplete = Url.Action("MatchMakerMaps", "Autocomplete")})</span>
</div>
}
<input type="submit" value="Save Bans" />
</form>
2 changes: 2 additions & 0 deletions Zero-K.info/Views/Shared/TopMenu.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
<li><a href="@Url.Action("Index", "Home")">Home</a></li>
<li><a href="@Url.Action("UnlockList", "My")">Unlocks</a></li>
<li><a href="@Url.Action("Commanders", "My")">Commanders</a></li>
<!-- TODO: Uncomment ban link after sufficient MM testing on live server -->
<!-- <a href="@Url.Action("Index", "MapBans")">Map Bans</a></li> -->
<li><a href="@Url.Action("UserVotes", "Poll", new{id = Global.AccountID})">Polls</a></li>
</ul>
</li>
Expand Down
2 changes: 2 additions & 0 deletions Zero-K.info/asp.net.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@
<Compile Include="Controllers\GithubController.cs" />
<Compile Include="Controllers\LobbyController.cs" />
<Compile Include="Controllers\LobbyNewsController.cs" />
<Compile Include="Controllers\MapBansController.cs" />
<Compile Include="Controllers\PlanetwarsAdminController.cs" />
<Compile Include="Controllers\ReplaysController.cs" />
<Compile Include="Controllers\TourneyController.cs" />
Expand Down Expand Up @@ -1578,6 +1579,7 @@
<Content Include="Views\Lobby\LobbyChat.cshtml" />
<Content Include="Views\Lobby\LobbyChatMessages.cshtml" />
<Content Include="Views\Shared\ChatNotification.cshtml" />
<Content Include="Views\MapBans\MapBansIndex.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\_ViewStart.cshtml" />
Expand Down
1 change: 1 addition & 0 deletions ZkData/Ef/Account.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ public static double AdjustEloWeight(double currentWeight, double sumWeight, int
public virtual ICollection<AccountCampaignVar> AccountCampaignVars { get; set; }
public virtual ICollection<AccountForumVote> AccountForumVotes { get; set; }
public virtual ICollection<AccountIP> AccountIPs { get; set; }
public virtual ICollection<AccountMapBan> AccountMapBans { get; set; }
public virtual ICollection<AccountRole> AccountRolesByAccountID { get; set; }
public virtual ICollection<AccountUnlock> AccountUnlocks { get; set; }
public virtual ICollection<AccountUserID> AccountUserIDs { get; set; }
Expand Down
25 changes: 25 additions & 0 deletions ZkData/Ef/AccountMapBan.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace ZkData
{
public class AccountMapBan
{
[Key]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int AccountID { get; set; }
[Key]
[Column(Order = 1)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int BannedMapResourceID { get; set; }
[Key]
[Column(Order = 2)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Rank { get; set; }

public virtual Account Account { get; set; }
public virtual Resource Resource { get; set; }
}
}
1 change: 1 addition & 0 deletions ZkData/Ef/Resource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public class Resource
public virtual ICollection<ResourceDependency> ResourceDependencies { get; set; } = new HashSet<ResourceDependency>();
public virtual ICollection<SpringBattle> SpringBattlesByModID { get; set; } = new HashSet<SpringBattle>();
public virtual ICollection<SpringBattle> SpringBattlesByMapResourceID { get; set; } = new HashSet<SpringBattle>();
public virtual ICollection<AccountMapBan> BansByAccountID { get; set; } = new HashSet<AccountMapBan>();


[NotMapped]
Expand Down
29 changes: 29 additions & 0 deletions ZkData/Migrations/202006162227037_AddAccountMapBans.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions ZkData/Migrations/202006162227037_AddAccountMapBans.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace ZkData.Migrations
{
using System;
using System.Data.Entity.Migrations;

public partial class AddAccountMapBans : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.AccountMapBans",
c => new
{
AccountID = c.Int(nullable: false),
BannedMapResourceID = c.Int(nullable: false),
Rank = c.Int(nullable: false),
})
.PrimaryKey(t => new { t.AccountID, t.BannedMapResourceID, t.Rank })
.ForeignKey("dbo.Resources", t => t.BannedMapResourceID)
.ForeignKey("dbo.Accounts", t => t.AccountID)
.Index(t => t.AccountID);

}

public override void Down()
{
DropForeignKey("dbo.AccountMapBans", "AccountID", "dbo.Accounts");
DropForeignKey("dbo.AccountMapBans", "BannedMapResourceID", "dbo.Resources");
DropIndex("dbo.AccountMapBans", new[] { "AccountID" });
DropTable("dbo.AccountMapBans");
}
}
}
Loading

0 comments on commit dacb3e4

Please sign in to comment.