diff --git a/WebHostLib/static/styles/minecraftTracker.css b/WebHostLib/static/styles/minecraftTracker.css
new file mode 100644
index 0000000000..8000a726d0
--- /dev/null
+++ b/WebHostLib/static/styles/minecraftTracker.css
@@ -0,0 +1,81 @@
+#player-tracker-wrapper{
+ margin: 0;
+}
+
+#inventory-table{
+ border-top: 2px solid #000000;
+ border-left: 2px solid #000000;
+ border-right: 2px solid #000000;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ padding: 3px 3px 10px;
+ width: 324px;
+ background-color: #42b149;
+}
+
+#inventory-table td{
+ width: 40px;
+ height: 40px;
+ text-align: center;
+ vertical-align: middle;
+}
+
+#inventory-table img{
+ height: 100%;
+ max-width: 40px;
+ max-height: 40px;
+ filter: grayscale(100%) contrast(75%) brightness(30%);
+}
+
+#inventory-table img.acquired{
+ filter: none;
+}
+
+#inventory-table div.counted-item {
+ position: relative;
+}
+
+#inventory-table div.item-count {
+ position: absolute;
+ color: white;
+ font-family: "Courier New", monospace;
+ font-weight: bold;
+ font-size: 20px;
+ bottom: 0px;
+ right: 4px;
+}
+
+#location-table{
+ width: 324px;
+ border-left: 2px solid #000000;
+ border-right: 2px solid #000000;
+ border-bottom: 2px solid #000000;
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+ background-color: #42b149;
+ padding: 0 3px 3px;
+}
+
+#location-table th{
+ vertical-align: middle;
+ text-align: left;
+ padding-right: 10px;
+}
+
+#location-table td{
+ padding-top: 2px;
+ padding-bottom: 2px;
+ padding-right: 5px;
+ line-height: 20px;
+}
+
+#location-table td.counter{
+ padding-right: 8px;
+ text-align: right;
+}
+
+#location-table img{
+ height: 100%;
+ max-width: 30px;
+ max-height: 30px;
+}
diff --git a/WebHostLib/templates/minecraftTracker.html b/WebHostLib/templates/minecraftTracker.html
new file mode 100644
index 0000000000..5eda5fa062
--- /dev/null
+++ b/WebHostLib/templates/minecraftTracker.html
@@ -0,0 +1,70 @@
+
+
+
+ {{ player_name }}'s Tracker
+
+
+
+
+
+
+
+
+
+
+ | Location |
+ Checked |
+
+
+
+ {% for name in checked_locations %}
+
+ | {{ name | location_name}} |
+ ✔ |
+
+ {%- endfor -%}
+ {% for name in not_checked_locations %}
+
+ | {{ name | location_name}} |
+ |
+
+ {%- endfor -%}
+
+
+
+
+
diff --git a/WebHostLib/tracker.py b/WebHostLib/tracker.py
index 6c038e8e3f..638da74d56 100644
--- a/WebHostLib/tracker.py
+++ b/WebHostLib/tracker.py
@@ -424,6 +424,78 @@ def getPlayerTracker(tracker: UUID, tracked_team: int, tracked_player: int):
key_locations=player_small_key_locations[tracked_player],
big_key_locations=player_big_key_locations[tracked_player],
**display_data)
+ elif games[tracked_player] == "Minecraft":
+ minecraft_icons = {
+ "Wooden Pickaxe": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/d/d2/Wooden_Pickaxe_JE3_BE3.png",
+ "Stone Pickaxe": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/c/c4/Stone_Pickaxe_JE2_BE2.png",
+ "Iron Pickaxe": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/d/d1/Iron_Pickaxe_JE3_BE2.png",
+ "Diamond Pickaxe": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/e/e7/Diamond_Pickaxe_JE3_BE3.png",
+ "Wooden Sword": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/d/d5/Wooden_Sword_JE2_BE2.png",
+ "Stone Sword": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/b/b1/Stone_Sword_JE2_BE2.png",
+ "Iron Sword": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/8/8e/Iron_Sword_JE2_BE2.png",
+ "Diamond Sword": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/4/44/Diamond_Sword_JE3_BE3.png",
+ "Leather Tunic": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/b/b7/Leather_Tunic_JE4_BE2.png",
+ "Iron Chestplate": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/3/31/Iron_Chestplate_JE2_BE2.png",
+ "Diamond Chestplate": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/e/e0/Diamond_Chestplate_JE3_BE2.png",
+ "Iron Ingot": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/f/fc/Iron_Ingot_JE3_BE2.png",
+ "Brewing Stand": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/f/fa/Brewing_Stand.png",
+ "Ender Pearl": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/f/f6/Ender_Pearl_JE3_BE2.png",
+ "Bucket": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/f/fc/Bucket_JE2_BE2.png",
+ "Bow": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/a/ab/Bow_%28Pull_2%29_JE1_BE1.png",
+ "Shield": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/c/c6/Shield_JE2_BE1.png",
+ "Block of Iron": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/7/7e/Block_of_Iron_JE4_BE3.png",
+ "Red Bed": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/d/dc/Red_Bed_JE4_BE3.png",
+ "Netherite Scrap": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/3/33/Netherite_Scrap_JE2_BE1.png",
+ "Flint and Steel": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/9/94/Flint_and_Steel_JE4_BE2.png",
+ "Enchanting Table": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/3/31/Enchanting_Table.gif",
+ "Fishing Rod": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/7/7f/Fishing_Rod_JE2_BE2.png",
+ "Campfire": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/9/91/Campfire_JE2_BE2.gif",
+ "Water Bottle": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/7/75/Water_Bottle_JE2_BE2.png",
+ "Dragon Head": "https://static.wikia.nocookie.net/minecraft_gamepedia/images/b/b6/Dragon_Head.png",
+ }
+
+ display_data = {}
+
+ # Determine display for progressive items
+ progressive_items = {
+ "Progressive Tools": 45013,
+ "Progressive Weapons": 45012,
+ "Progressive Armor": 45014
+ }
+ progressive_names = {
+ "Progressive Tools": ["Wooden Pickaxe", "Stone Pickaxe", "Iron Pickaxe", "Diamond Pickaxe"],
+ "Progressive Weapons": ["Wooden Sword", "Stone Sword", "Iron Sword", "Diamond Sword"],
+ "Progressive Armor": ["Leather Tunic", "Iron Chestplate", "Diamond Chestplate"]
+ }
+ for item_name, item_id in progressive_items.items():
+ level = min(inventory[item_id], len(progressive_names[item_name])-1)
+ display_name = progressive_names[item_name][level]
+ base_name = item_name.split(maxsplit=1)[1].lower()
+ display_data[base_name+"_url"] = minecraft_icons[display_name]
+
+ # Multi-items
+ multi_items = {
+ "3 Ender Pearls": 45029,
+ "8 Netherite Scrap": 45015
+ }
+ for item_name, item_id in multi_items.items():
+ base_name = item_name.split()[-1].lower()
+ count = inventory[item_id]
+ if count > 0:
+ display_data[base_name+"_count"] = count
+
+ # Victory condition
+ game_state = multisave.get("client_game_state", {}).get((tracked_team, tracked_player), 0)
+ display_data['game_finished'] = True if game_state == 30 else False # found in NetUtils
+
+
+ checked_locations = multisave.get("location_checks", {}).get((tracked_team, tracked_player), set())
+ return render_template("minecraftTracker.html",
+ inventory=inventory, icons=minecraft_icons, acquired_items={lookup_any_item_id_to_name[id] for id in inventory},
+ player=tracked_player, team=tracked_team, room=room, player_name=player_name,
+ checked_locations=checked_locations, not_checked_locations=set(locations[tracked_player])-checked_locations,
+ **display_data)
+
else:
checked_locations = multisave.get("location_checks", {}).get((tracked_team, tracked_player), set())
return render_template("genericTracker.html",