Skip to content

Commit dd8602a

Browse files
authored
Merge pull request #582 from ItzKatze/master
feat: prototype map and map system
2 parents 34f525c + 7926f97 commit dd8602a

11 files changed

Lines changed: 333 additions & 775 deletions

File tree

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
package net.swofty.type.generic.utility;
2+
3+
import lombok.Getter;
4+
import net.minestom.server.component.DataComponents;
5+
import net.minestom.server.coordinate.Pos;
6+
import net.minestom.server.entity.Entity;
7+
import net.minestom.server.entity.EntityType;
8+
import net.minestom.server.entity.metadata.other.ItemFrameMeta;
9+
import net.minestom.server.instance.Instance;
10+
import net.minestom.server.item.ItemStack;
11+
import net.minestom.server.item.Material;
12+
import net.minestom.server.network.packet.server.play.MapDataPacket;
13+
import net.minestom.server.utils.Direction;
14+
import net.swofty.type.generic.user.HypixelPlayer;
15+
16+
import java.io.ByteArrayInputStream;
17+
import java.io.IOException;
18+
import java.util.Base64;
19+
import java.util.List;
20+
import java.util.concurrent.ConcurrentHashMap;
21+
import java.util.zip.GZIPInputStream;
22+
23+
public abstract class AbstractMapSystem {
24+
private static final ConcurrentHashMap<Integer, byte[]> MAP_COLOR_CACHE = new ConcurrentHashMap<>(64, 0.75f, 1);
25+
26+
private MapDataPacket[] mapPacketCache;
27+
private volatile boolean initialized = false;
28+
29+
protected abstract MapConfiguration getConfiguration();
30+
protected abstract String[] getCompressedMapData();
31+
32+
private void initializeMapPackets() {
33+
if (initialized) return;
34+
35+
synchronized (this) {
36+
if (initialized) return;
37+
38+
MapConfiguration config = getConfiguration();
39+
String[] compressedData = getCompressedMapData();
40+
int totalMaps = config.getColumns() * config.getRows();
41+
42+
if (compressedData.length != totalMaps) {
43+
throw new IllegalStateException(
44+
"Expected " + totalMaps + " map data strings, got " + compressedData.length
45+
);
46+
}
47+
48+
mapPacketCache = new MapDataPacket[totalMaps];
49+
50+
for (int i = 0; i < totalMaps; i++) {
51+
mapPacketCache[i] = new MapDataPacket(
52+
1 + i,
53+
(byte) 0,
54+
false,
55+
false,
56+
List.of(),
57+
new MapDataPacket.ColorContent(
58+
(byte) 128,
59+
(byte) 128,
60+
(byte) 0,
61+
(byte) 0,
62+
decodeMapColors(compressedData[i])
63+
)
64+
);
65+
}
66+
67+
initialized = true;
68+
}
69+
}
70+
71+
public void placeItemFrames(Instance instance) {
72+
MapConfiguration c = getConfiguration();
73+
int yStart = c.topLeft.blockY();
74+
75+
for (int row = 0; row < c.rows; row++) {
76+
int y = yStart - row;
77+
78+
for (int col = 0; col < c.columns; col++) {
79+
Pos pos = c.facing.resolvePosition(c.topLeft, col, y);
80+
81+
Entity frame = new Entity(EntityType.ITEM_FRAME);
82+
int index = row * c.columns + col;
83+
int id = 1 + index;
84+
85+
frame.editEntityMeta(ItemFrameMeta.class, meta -> {
86+
meta.setItem(
87+
ItemStack.builder(Material.FILLED_MAP)
88+
.set(DataComponents.MAP_ID, id)
89+
.build()
90+
);
91+
meta.setDirection(c.facing.getAttachmentFace());
92+
});
93+
94+
frame.setInstance(instance, pos);
95+
}
96+
}
97+
}
98+
99+
public void sendMapData(HypixelPlayer player) {
100+
if (!initialized) {
101+
initializeMapPackets();
102+
}
103+
player.sendPackets(mapPacketCache);
104+
}
105+
106+
protected byte[] decodeMapColors(String compressedData) {
107+
int cacheKey = compressedData.hashCode();
108+
byte[] cached = MAP_COLOR_CACHE.get(cacheKey);
109+
if (cached != null) {
110+
return cached;
111+
}
112+
113+
try {
114+
byte[] decompressed = Base64.getDecoder().decode(compressedData);
115+
try (ByteArrayInputStream bais = new ByteArrayInputStream(decompressed);
116+
GZIPInputStream gis = new GZIPInputStream(bais)) {
117+
byte[] result = gis.readAllBytes();
118+
MAP_COLOR_CACHE.put(cacheKey, result);
119+
return result;
120+
}
121+
} catch (IOException e) {
122+
throw new RuntimeException("Failed to decode map colors for " + getClass().getSimpleName(), e);
123+
}
124+
}
125+
126+
public static class MapConfiguration {
127+
@Getter private final Pos topLeft;
128+
@Getter private final Pos bottomRight;
129+
@Getter private final MapFacing facing;
130+
131+
@Getter private final int columns;
132+
@Getter private final int rows;
133+
134+
public MapConfiguration(Pos topLeft, Pos bottomRight, MapFacing facing) {
135+
this.topLeft = topLeft;
136+
this.bottomRight = bottomRight;
137+
this.facing = facing;
138+
139+
this.rows = topLeft.blockY() - bottomRight.blockY() + 1;
140+
141+
if (facing == MapFacing.WEST || facing == MapFacing.EAST) {
142+
this.columns = Math.abs(topLeft.blockZ() - bottomRight.blockZ()) + 1;
143+
} else {
144+
this.columns = Math.abs(topLeft.blockX() - bottomRight.blockX()) + 1;
145+
}
146+
}
147+
}
148+
149+
public enum MapFacing {
150+
WEST {
151+
public Pos resolvePosition(Pos tl, int col, int y) {
152+
return new Pos(tl.blockX(), y, tl.blockZ() - col + 0.5);
153+
}
154+
public Direction getAttachmentFace() { return Direction.EAST; }
155+
},
156+
EAST {
157+
public Pos resolvePosition(Pos tl, int col, int y) {
158+
return new Pos(tl.blockX(), y, tl.blockZ() + col + 0.5);
159+
}
160+
public Direction getAttachmentFace() { return Direction.WEST; }
161+
},
162+
NORTH {
163+
public Pos resolvePosition(Pos tl, int col, int y) {
164+
return new Pos(tl.blockX() + col + 0.5, y, tl.blockZ());
165+
}
166+
public Direction getAttachmentFace() { return Direction.SOUTH; }
167+
},
168+
SOUTH {
169+
public Pos resolvePosition(Pos tl, int col, int y) {
170+
return new Pos(tl.blockX() - col + 0.5, y, tl.blockZ());
171+
}
172+
public Direction getAttachmentFace() { return Direction.NORTH; }
173+
};
174+
175+
public abstract Pos resolvePosition(Pos topLeft, int col, int y);
176+
public abstract Direction getAttachmentFace();
177+
}
178+
179+
}

type.hub/src/main/java/net/swofty/type/hub/TypeHubLoader.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import net.swofty.type.hub.darkauction.DarkAuctionDisplay;
2727
import net.swofty.type.hub.runes.RuneEntityImpl;
2828
import net.swofty.type.hub.tab.HubServerModule;
29-
import net.swofty.type.hub.util.HubMapUtility;
29+
import net.swofty.type.hub.util.HubMap;
3030
import net.swofty.type.skyblockgeneric.SkyBlockGenericLoader;
3131
import net.swofty.type.skyblockgeneric.darkauction.DarkAuctionHandler;
3232
import net.swofty.type.skyblockgeneric.entity.GlassDisplay;
@@ -127,8 +127,8 @@ public void afterInitialize(MinecraftServer server) {
127127
darkAuctionDisplay.update();
128128
});
129129

130-
// Place maps in the hub
131-
HubMapUtility.setMaps(HypixelConst.getInstanceContainer());
130+
HubMap hubMap = new HubMap();
131+
hubMap.placeItemFrames(HypixelConst.getInstanceContainer());
132132
}
133133

134134
@Override

type.hub/src/main/java/net/swofty/type/hub/events/ActionPlayerSpawn.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import net.swofty.type.generic.event.EventNodes;
66
import net.swofty.type.generic.event.HypixelEvent;
77
import net.swofty.type.generic.event.HypixelEventClass;
8-
import net.swofty.type.hub.util.HubMapUtility;
8+
import net.swofty.type.hub.util.HubMap;
99
import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer;
1010

1111
public class ActionPlayerSpawn implements HypixelEventClass {
@@ -14,6 +14,8 @@ public class ActionPlayerSpawn implements HypixelEventClass {
1414
@HypixelEvent(node = EventNodes.PLAYER, requireDataLoaded = false, isAsync = true)
1515
public void run(PlayerSpawnEvent event) {
1616
final SkyBlockPlayer player = (SkyBlockPlayer) event.getPlayer();
17-
HubMapUtility.sendMapData(player);
17+
18+
HubMap hubMap = new HubMap();
19+
hubMap.sendMapData(player);
1820
}
1921
}

type.hub/src/main/java/net/swofty/type/hub/npcs/NPCBiblio.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public String texture(HypixelPlayer player) {
2727

2828
@Override
2929
public Pos position(HypixelPlayer player) {
30-
return new Pos(7.6, 71, -99.8, 90, 0);
30+
return new Pos(14, 72, -106, 50, 0);
3131
}
3232

3333
@Override

type.hub/src/main/java/net/swofty/type/hub/npcs/NPCClerkSeraphine.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public String texture(HypixelPlayer player) {
2828

2929
@Override
3030
public Pos position(HypixelPlayer player) {
31-
return new Pos(11.5, 71, -101, 90, 0);
31+
return new Pos(4.5, 72, -104.5, 0, 0);
3232
}
3333

3434
@Override

type.hub/src/main/java/net/swofty/type/hub/npcs/NPCElizabeth.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public String texture(HypixelPlayer player) {
3131

3232
@Override
3333
public Pos position(HypixelPlayer player) {
34-
return new Pos(0, 71, -101, -90, 0);
34+
return new Pos(-3.5, 72, -101.5, -90, 0);
3535
}
3636

3737
@Override

0 commit comments

Comments
 (0)