Skip to content

Commit 59f17a3

Browse files
committed
Cleanup client resource manager so it is now read only view of the server state. Lighten up networking layer for syncing the storage state, this should improve speed and reduce bugs
1 parent 9ee3633 commit 59f17a3

38 files changed

+525
-262
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ sourceSets {
3030
compileClasspath += main.compileClasspath + core.output + networking.output
3131
}
3232
building {
33-
compileClasspath += main.compileClasspath + core.output + gui.output
33+
compileClasspath += main.compileClasspath + core.output + gui.output + networking.output
3434
}
3535
selections {
3636
compileClasspath += main.compileClasspath + core.output + building.output + networking.output

src/building/java/net/remmintan/mods/minefortress/blocks/building/BuildingHireHandler.kt

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
package net.remmintan.mods.minefortress.blocks.building
22

33
import net.minecraft.nbt.NbtCompound
4-
import net.minecraft.nbt.NbtList
5-
import net.remmintan.mods.minefortress.core.dtos.ItemInfo
64
import net.remmintan.mods.minefortress.core.dtos.professions.HireProgressInfo
7-
import net.remmintan.mods.minefortress.core.dtos.professions.ProfessionHireInfo
85
import net.remmintan.mods.minefortress.core.interfaces.blueprints.ProfessionType
96
import net.remmintan.mods.minefortress.core.interfaces.buildings.IBuildingHireHandler
107
import net.remmintan.mods.minefortress.core.interfaces.buildings.IServerBuildingsManager
@@ -20,8 +17,8 @@ class BuildingHireHandler : IBuildingHireHandler {
2017
private var buildingsManager: IServerBuildingsManager? = null
2118
private var resourceManger: IServerResourceManager? = null
2219
private var resourceHelper: IServerResourceHelper? = null
20+
private var professionIds: List<String> = emptyList()
2321

24-
private var professions: List<ProfessionHireInfo> = emptyList()
2522
private var hireQueues = mutableMapOf<String, Queue<HireRequest>>()
2623
private var hireProgresses = mutableMapOf<String, HireProgressInfo>()
2724

@@ -39,18 +36,7 @@ class BuildingHireHandler : IBuildingHireHandler {
3936
this.buildingsManager = buildingsManager
4037
this.resourceManger = resourceManager
4138
this.resourceHelper = resourceHelper
42-
43-
professions = professionManager
44-
.getProfessionsByType(professionType)
45-
.filter { buildingsManager.hasRequiredBuilding(it.requirementType, it.requirementLevel, 0) }
46-
.map {
47-
ProfessionHireInfo(
48-
it.id,
49-
it.title,
50-
it.icon,
51-
it.itemsRequirement.map { r -> ItemInfo(r.item, r.count) }
52-
)
53-
}
39+
this.professionIds = professionManager.getProfessionsByType(professionType).map { it.id }
5440
}
5541

5642
fun tick() {
@@ -85,7 +71,9 @@ class BuildingHireHandler : IBuildingHireHandler {
8571
}
8672
}
8773

88-
override fun getProfessions(): List<ProfessionHireInfo> = professions
74+
override fun getProfessionIds(): List<String> {
75+
return professionIds
76+
}
8977

9078
override fun getHireProgress(professionId: String): HireProgressInfo {
9179
if (buildingsManager == null) {
@@ -127,10 +115,6 @@ class BuildingHireHandler : IBuildingHireHandler {
127115
val rootTag = NbtCompound()
128116

129117
// professions
130-
val profList = NbtList().apply {
131-
professions.forEach { add(it.toNbt()) }
132-
}
133-
134118
val queuesTag = NbtCompound()
135119
hireQueues.forEach { (professionId, queue) ->
136120
val queueTag = NbtCompound()
@@ -143,21 +127,18 @@ class BuildingHireHandler : IBuildingHireHandler {
143127
}
144128

145129
val progressesTag = NbtCompound()
146-
professions.map { it.professionId }.forEach {
130+
professionIds.forEach {
147131
val hireProgress = getHireProgress(it)
148132
progressesTag.put(it, hireProgress.toNbt())
149133
}
150134

151-
rootTag.put("professions", profList)
152135
rootTag.put("queues", queuesTag)
153136
rootTag.put("progresses", progressesTag)
154137

155138
return rootTag
156139
}
157140

158141
fun updateFromNbt(tag: NbtCompound) {
159-
val professions = tag.getList("professions", 10).map { ProfessionHireInfo.fromNbt(it as NbtCompound) }
160-
this.professions = professions
161142

162143
val queuesTag = tag.getCompound("queues")
163144
queuesTag.keys.forEach { professionId ->

src/building/java/net/remmintan/mods/minefortress/blocks/building/FortressBuildingBlockEntity.kt

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import net.minecraft.registry.tag.BlockTags
1717
import net.minecraft.screen.NamedScreenHandlerFactory
1818
import net.minecraft.screen.PropertyDelegate
1919
import net.minecraft.screen.ScreenHandler
20+
import net.minecraft.server.network.ServerPlayerEntity
2021
import net.minecraft.server.world.ServerWorld
2122
import net.minecraft.text.Text
2223
import net.minecraft.util.math.BlockPos
@@ -25,13 +26,19 @@ import net.minecraft.world.World
2526
import net.remmintan.mods.minefortress.blocks.FortressBlocks
2627
import net.remmintan.mods.minefortress.core.dtos.buildings.BarColor
2728
import net.remmintan.mods.minefortress.core.dtos.buildings.BlueprintMetadata
29+
import net.remmintan.mods.minefortress.core.dtos.buildings.BuildingScreenInfo
2830
import net.remmintan.mods.minefortress.core.dtos.buildings.HudBar
31+
import net.remmintan.mods.minefortress.core.dtos.professions.ProfessionCost
32+
import net.remmintan.mods.minefortress.core.dtos.professions.ProfessionHireInfo
2933
import net.remmintan.mods.minefortress.core.interfaces.automation.area.IAutomationArea
3034
import net.remmintan.mods.minefortress.core.interfaces.blueprints.ProfessionType
3135
import net.remmintan.mods.minefortress.core.interfaces.buildings.IFortressBuilding
3236
import net.remmintan.mods.minefortress.core.utils.ClientModUtils
37+
import net.remmintan.mods.minefortress.core.utils.ServerModUtils
3338
import net.remmintan.mods.minefortress.core.utils.getManagersProvider
3439
import net.remmintan.mods.minefortress.gui.building.BuildingScreenHandler
40+
import net.remmintan.mods.minefortress.networking.helpers.FortressServerNetworkHelper
41+
import net.remmintan.mods.minefortress.networking.s2c.S2CSyncBuildingScreenInfo
3542
import org.slf4j.Logger
3643
import org.slf4j.LoggerFactory
3744
import java.util.*
@@ -103,7 +110,6 @@ class FortressBuildingBlockEntity(pos: BlockPos?, state: BlockState?) :
103110

104111
if (world is ServerWorld) {
105112
val provider = world.server.getManagersProvider(fortressPos!!)
106-
checkNotNull(provider)
107113

108114
it.init(
109115
professionType,
@@ -177,10 +183,8 @@ class FortressBuildingBlockEntity(pos: BlockPos?, state: BlockState?) :
177183

178184

179185
val hireProgress = hireHandler
180-
.getProfessions()
181-
.map {
182-
hireHandler.getHireProgress(it.professionId)
183-
}
186+
.getProfessionIds()
187+
.map { hireHandler.getHireProgress(it) }
184188
.filter { it.queueLength > 0 }
185189
.minByOrNull { it.queueLength }
186190
?.progress
@@ -199,10 +203,40 @@ class FortressBuildingBlockEntity(pos: BlockPos?, state: BlockState?) :
199203
return list
200204
}
201205

206+
override fun constructAndSendBuildingScreenInfo(player: ServerPlayerEntity) {
207+
val managersProvider = ServerModUtils.getManagersProvider(player).orElseThrow()
208+
209+
val professionsManager = managersProvider.professionsManager
210+
val buildingsManager = managersProvider.buildingsManager
211+
val resourceHelper = managersProvider.resourceHelper
212+
213+
val professions = professionsManager
214+
.getProfessionsByType(metadata.requirement.type)
215+
.filter { buildingsManager.hasRequiredBuilding(it.requirementType, it.requirementLevel, 0) }
216+
.map {
217+
ProfessionHireInfo(
218+
it.id,
219+
it.title,
220+
it.icon,
221+
it.itemsRequirement.map { r ->
222+
ProfessionCost(
223+
r.item,
224+
r.count,
225+
resourceHelper.getCountIncludingSimilar(item = r.item)
226+
)
227+
}
228+
)
229+
}
230+
231+
val buildingScreenInfo = BuildingScreenInfo(professions)
232+
val packet = S2CSyncBuildingScreenInfo(buildingScreenInfo)
233+
FortressServerNetworkHelper.send(player, S2CSyncBuildingScreenInfo.CHANNEL, packet)
234+
}
235+
202236
override fun createMenu(syncId: Int, playerInventory: PlayerInventory?, player: PlayerEntity?): ScreenHandler {
203237
val propertyDelegate = object : PropertyDelegate {
204238
override fun get(index: Int): Int {
205-
return when(index) {
239+
return when (index) {
206240
0 -> pos.x
207241
1 -> pos.y
208242
2 -> pos.z
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package net.remmintan.mods.minefortress.core.dtos
2+
3+
enum class EnoughResourceState {
4+
5+
ENOUGH,
6+
NOT_ENOUGH,
7+
PENDING
8+
9+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package net.remmintan.mods.minefortress.core.dtos.buildings
2+
3+
import net.minecraft.network.PacketByteBuf
4+
import net.remmintan.mods.minefortress.core.dtos.professions.ProfessionHireInfo
5+
6+
data class BuildingScreenInfo(
7+
val professions: List<ProfessionHireInfo>
8+
) {
9+
fun writeToPacketByteBuf(buf: PacketByteBuf) {
10+
buf.writeCollection(professions) { b, it -> it.writeToPacketByteBuf(b) }
11+
}
12+
13+
companion object {
14+
15+
fun readFromPacketByteBuf(buf: PacketByteBuf): BuildingScreenInfo {
16+
val professions = buf.readCollection({ mutableListOf<ProfessionHireInfo>() }) {
17+
ProfessionHireInfo.readFromPacketByteBuf(it)
18+
}
19+
20+
return BuildingScreenInfo(professions)
21+
}
22+
23+
}
24+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package net.remmintan.mods.minefortress.core.dtos.professions
2+
3+
import net.minecraft.item.Item
4+
import net.minecraft.network.PacketByteBuf
5+
6+
data class ProfessionCost(val item: Item, val requiredAmount: Int, val totalAmount: Long) {
7+
8+
val enoughItems: Boolean = totalAmount >= requiredAmount
9+
10+
fun writeToPacketByteBuf(buf: PacketByteBuf) {
11+
buf.writeInt(Item.getRawId(item))
12+
buf.writeInt(requiredAmount)
13+
buf.writeLong(totalAmount)
14+
}
15+
16+
companion object {
17+
18+
fun readFromPacketByteBuf(buf: PacketByteBuf): ProfessionCost {
19+
val item = Item.byRawId(buf.readInt())
20+
val requiredAmount = buf.readInt()
21+
val totalAmount = buf.readLong()
22+
23+
return ProfessionCost(item, requiredAmount, totalAmount)
24+
}
25+
26+
}
27+
28+
}
Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,31 @@
11
package net.remmintan.mods.minefortress.core.dtos.professions
22

33
import net.minecraft.item.ItemStack
4-
import net.minecraft.nbt.NbtCompound
5-
import net.minecraft.nbt.NbtList
6-
import net.remmintan.mods.minefortress.core.dtos.ItemInfo
4+
import net.minecraft.network.PacketByteBuf
75

86
data class ProfessionHireInfo(
97
val professionId: String,
108
val professionName: String,
119
val professionItem: ItemStack,
12-
val professionCost: List<ItemInfo>
10+
val professionCost: List<ProfessionCost>
1311
) {
14-
fun toNbt(): NbtCompound {
15-
val nbt = NbtCompound()
16-
nbt.putString("professionId", professionId)
17-
nbt.putString("professionName", professionName)
18-
nbt.put("professionItem", professionItem.writeNbt(NbtCompound()))
19-
nbt.put("professionCost", NbtList().apply { professionCost.forEach { add(it.toNbt()) } })
20-
return nbt
12+
fun writeToPacketByteBuf(buf: PacketByteBuf) {
13+
buf.writeString(professionId)
14+
buf.writeString(professionName)
15+
buf.writeItemStack(professionItem)
16+
buf.writeCollection(professionCost) { b, it -> it.writeToPacketByteBuf(b) }
2117
}
2218

2319
companion object {
24-
fun fromNbt(nbt: NbtCompound): ProfessionHireInfo {
25-
return ProfessionHireInfo(
26-
nbt.getString("professionId"),
27-
nbt.getString("professionName"),
28-
ItemStack.fromNbt(nbt.getCompound("professionItem")),
29-
nbt.getList("professionCost", 10).map { ItemInfo.fromNbt(it as NbtCompound) }
30-
)
20+
fun readFromPacketByteBuf(buf: PacketByteBuf): ProfessionHireInfo {
21+
val professionId = buf.readString()
22+
val professionName = buf.readString()
23+
val professionItem = buf.readItemStack()
24+
val professionCosts =
25+
buf.readCollection({ mutableListOf<ProfessionCost>() }) { ProfessionCost.readFromPacketByteBuf(it) }
26+
.toList()
27+
28+
return ProfessionHireInfo(professionId, professionName, professionItem, professionCosts)
3129
}
3230
}
3331
}
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package net.remmintan.mods.minefortress.core.interfaces.buildings
22

33
import net.remmintan.mods.minefortress.core.dtos.professions.HireProgressInfo
4-
import net.remmintan.mods.minefortress.core.dtos.professions.ProfessionHireInfo
54

65
interface IBuildingHireHandler {
76
fun hire(professionId: String)
8-
fun getProfessions(): List<ProfessionHireInfo>
7+
fun getProfessionIds(): List<String>
98
fun getHireProgress(professionId: String): HireProgressInfo
109
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package net.remmintan.mods.minefortress.core.interfaces.buildings
2+
3+
import net.minecraft.client.MinecraftClient
4+
import net.minecraft.util.math.BlockPos
5+
import net.remmintan.mods.minefortress.core.dtos.buildings.BuildingScreenInfo
6+
import net.remmintan.mods.minefortress.core.dtos.professions.ProfessionHireInfo
7+
8+
interface IClientBuildingScreenInfoService {
9+
10+
fun requestUpdate(buildingPos: BlockPos)
11+
fun syncState(info: BuildingScreenInfo)
12+
fun getProfessions(): List<ProfessionHireInfo>
13+
fun tick(client: MinecraftClient)
14+
15+
}

src/core/java/net/remmintan/mods/minefortress/core/interfaces/buildings/IFortressBuilding.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import net.minecraft.block.entity.BlockEntity;
55
import net.minecraft.entity.mob.HostileEntity;
66
import net.minecraft.item.ItemStack;
7+
import net.minecraft.server.network.ServerPlayerEntity;
78
import net.minecraft.util.math.BlockBox;
89
import net.minecraft.util.math.BlockPos;
910
import net.minecraft.world.Heightmap;
@@ -88,4 +89,6 @@ default boolean isPartOfTheBuilding(BlockPos pos) {
8889
IBuildingHireHandler getHireHandler();
8990

9091
List<HudBar> getBars();
92+
93+
void constructAndSendBuildingScreenInfo(ServerPlayerEntity player);
9194
}

0 commit comments

Comments
 (0)