1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
package gregtech.api.objects;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeChunkManager;
import net.minecraftforge.common.ForgeChunkManager.Ticket;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import gregtech.GT_Mod;
import gregtech.api.enums.GT_Values;
import gregtech.api.interfaces.IChunkLoader;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.util.GT_Log;
// This class handles re-initializing chunks after a server restart
public class GT_ChunkManager
implements ForgeChunkManager.OrderedLoadingCallback, ForgeChunkManager.PlayerOrderedLoadingCallback {
private Map<TileEntity, Ticket> registeredTickets = new HashMap<>();
public static GT_ChunkManager instance = new GT_ChunkManager();
public static void init() {
ForgeChunkManager.setForcedChunkLoadingCallback(GT_Mod.instance, instance);
// MinecraftForge.EVENT_BUS.register(instance);
}
@Override
public void ticketsLoaded(List<Ticket> tickets, World world) {}
// Determine if tickets should be kept. Based on if the ticket is a machine or working chunk ticket. Working chunk
// tickets are tossed
// and re-created when the machine re-activates. Machine tickets are kept only if the config
// alwaysReloadChunkloaders is true. Otherwise
// machine chunks are tossed and re-created only when the machine re-activates, similar to a Passive Anchor.
@Override
public List<Ticket> ticketsLoaded(List<Ticket> tickets, World world, int maxTicketCount) {
List<Ticket> validTickets = new ArrayList<>();
if (GT_Values.alwaysReloadChunkloaders) {
for (Ticket ticket : tickets) {
int x = ticket.getModData().getInteger("OwnerX");
int y = ticket.getModData().getInteger("OwnerY");
int z = ticket.getModData().getInteger("OwnerZ");
if (y > 0) {
TileEntity tile = world.getTileEntity(x, y, z);
if (tile != null && tile instanceof IGregTechTileEntity
&& ((IGregTechTileEntity) tile).isAllowedToWork()) {
ForgeChunkManager.forceChunk(ticket, new ChunkCoordIntPair(x >> 4, z >> 4));
if (!registeredTickets.containsKey(tile)) {
registeredTickets.put(tile, ticket);
if (((IGregTechTileEntity) tile).getMetaTileEntity() instanceof IChunkLoader)
ForgeChunkManager.forceChunk(
ticket,
((IChunkLoader) ((IGregTechTileEntity) tile).getMetaTileEntity())
.getActiveChunk());
validTickets.add(ticket);
}
}
}
}
}
return validTickets;
}
// Determine if player tickets should be kept. This is where a ticket list per player would be created and
// maintained. When
// a player join event occurs, their name/UUID/whatevs is compared against tickets on this list and those tickets
// reactivated.
// Since that info would be maintained/dealt with on a per-player startup, the list returned back to Forge is empty.
@Override
public ListMultimap<String, Ticket> playerTicketsLoaded(ListMultimap<String, Ticket> tickets, World world) {
// Not currently used, so just return an empty list.
return ArrayListMultimap.create();
}
// Request a chunk to be loaded for this machine
// may pass null chunk to load just the machine itself, if "alwaysReloadChunkloaders" is enabled in config
public static boolean requestPlayerChunkLoad(TileEntity owner, ChunkCoordIntPair chunkXZ, String player) {
if (!GT_Values.enableChunkloaders) return false;
if (!GT_Values.alwaysReloadChunkloaders && chunkXZ == null) return false;
if (GT_Values.debugChunkloaders && chunkXZ != null) GT_Log.out
.println("GT_ChunkManager: Chunk request: (" + chunkXZ.chunkXPos + ", " + chunkXZ.chunkZPos + ")");
if (instance.registeredTickets.containsKey(owner)) {
ForgeChunkManager.forceChunk(instance.registeredTickets.get(owner), chunkXZ);
} else {
Ticket ticket;
if (player.equals("")) ticket = ForgeChunkManager
.requestTicket(GT_Mod.instance, owner.getWorldObj(), ForgeChunkManager.Type.NORMAL);
else ticket = ForgeChunkManager
.requestPlayerTicket(GT_Mod.instance, player, owner.getWorldObj(), ForgeChunkManager.Type.NORMAL);
if (ticket == null) {
if (GT_Values.debugChunkloaders)
GT_Log.out.println("GT_ChunkManager: ForgeChunkManager.requestTicket failed");
return false;
}
if (GT_Values.debugChunkloaders) GT_Log.out.println(
"GT_ChunkManager: ticket issued for machine at: (" + owner.xCoord
+ ", "
+ owner.yCoord
+ ", "
+ owner.zCoord
+ ")");
NBTTagCompound tag = ticket.getModData();
tag.setInteger("OwnerX", owner.xCoord);
tag.setInteger("OwnerY", owner.yCoord);
tag.setInteger("OwnerZ", owner.zCoord);
ForgeChunkManager.forceChunk(ticket, chunkXZ);
if (GT_Values.alwaysReloadChunkloaders)
ForgeChunkManager.forceChunk(ticket, new ChunkCoordIntPair(owner.xCoord >> 4, owner.zCoord >> 4));
instance.registeredTickets.put(owner, ticket);
}
return true;
}
public static boolean requestChunkLoad(TileEntity owner, ChunkCoordIntPair chunkXZ) {
return requestPlayerChunkLoad(owner, chunkXZ, "");
}
public static void releaseChunk(TileEntity owner, ChunkCoordIntPair chunkXZ) {
if (!GT_Values.enableChunkloaders) return;
Ticket ticket = instance.registeredTickets.get(owner);
if (ticket != null) {
if (GT_Values.debugChunkloaders) GT_Log.out
.println("GT_ChunkManager: Chunk release: (" + chunkXZ.chunkXPos + ", " + chunkXZ.chunkZPos + ")");
ForgeChunkManager.unforceChunk(ticket, chunkXZ);
}
}
public static void releaseTicket(TileEntity owner) {
if (!GT_Values.enableChunkloaders) return;
Ticket ticket = instance.registeredTickets.get(owner);
if (ticket != null) {
if (GT_Values.debugChunkloaders) {
GT_Log.out.println(
"GT_ChunkManager: ticket released by machine at: (" + owner.xCoord
+ ", "
+ owner.yCoord
+ ", "
+ owner.zCoord
+ ")");
for (ChunkCoordIntPair chunk : ticket.getChunkList()) GT_Log.out
.println("GT_ChunkManager: Chunk release: (" + chunk.chunkXPos + ", " + chunk.chunkZPos + ")");
}
ForgeChunkManager.releaseTicket(ticket);
instance.registeredTickets.remove(owner);
}
}
public static void printTickets() {
GT_Log.out.println("GT_ChunkManager: Start forced chunks dump:");
instance.registeredTickets.forEach((machine, ticket) -> {
GT_Log.out.print(
"GT_ChunkManager: Chunks forced by the machine at (" + machine.xCoord
+ ", "
+ machine.yCoord
+ ", "
+ machine.zCoord
+ ")");
if (ticket.isPlayerTicket()) GT_Log.out.print(" Owner: " + ticket.getPlayerName());
GT_Log.out.print(" :");
for (ChunkCoordIntPair c : ticket.getChunkList()) {
GT_Log.out.print("(");
GT_Log.out.print(c.chunkXPos);
GT_Log.out.print(", ");
GT_Log.out.print(c.chunkZPos);
GT_Log.out.print("), ");
}
});
GT_Log.out.println("GT_ChunkManager: End forced chunks dump:");
}
}
|