Skip to content

Commit 181914d

Browse files
authored
Merge pull request #30 from way-zer/server-fix
修复一些bug
2 parents 0d86b27 + c610b03 commit 181914d

File tree

7 files changed

+96
-106
lines changed

7 files changed

+96
-106
lines changed

src/main/kotlin/cf/wayzer/contentsTweaker/PatchHandler.kt

+10-21
Original file line numberDiff line numberDiff line change
@@ -63,39 +63,28 @@ object PatchHandler {
6363
return "Node(key='$key')"
6464
}
6565

66-
interface WithObj {
67-
val obj: Any?
68-
val type: Class<*>?
66+
interface WithObj<T> {
67+
val obj: T
68+
val type: Class<*>
6969
val elementType: Class<*>? get() = null
7070
val keyType: Class<*>? get() = null
7171
}
7272

7373
//Node with obj, not Modifiable, use as simple node
74-
class ObjNode(override val parent: Node, key: String, override val obj: Any, override val type: Class<out Any> = obj.javaClass) :
75-
Node(key), WithObj
74+
class ObjNode<T : Any>(override val parent: Node, key: String, override val obj: T, override val type: Class<T> = obj.javaClass) :
75+
Node(key), WithObj<T>
7676

7777
interface Storable {
7878
val storeDepth: Int
7979
fun doSave()
8080
fun doRecover()
8181
}
8282

83-
interface Modifiable : WithObj, Storable {
84-
// /**
85-
// * 可直接修改[obj]对象.通过其他机制可保证还原
86-
// * true时: [doStore0]负责拷贝对象,并保存,由[recover]负责恢复
87-
// * false时: 由[Modifier]负责产生新对象并[setValue]
88-
// * */
89-
// val mutableObj: Boolean get() = false
90-
fun setValue(value: Any?)
91-
// fun doStore() {
92-
// if (mutableObj) error("mutable Modifiable need impl doStore0 to backup obj")
93-
// }
94-
//
95-
// fun recover() {
96-
// if (mutableObj) error("mutable Modifiable need impl recover to recover obj")
97-
// setValue(obj)
98-
// }
83+
interface Modifiable<T> : WithObj<T>, Storable {
84+
fun setValue(value: T)
85+
86+
@Suppress("UNCHECKED_CAST")
87+
fun setValueAny(value: Any?) = setValue(type.cast(value) as T)
9988
}
10089

10190
fun interface Modifier {

src/main/kotlin/cf/wayzer/contentsTweaker/resolvers/BaseModifier.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import cf.wayzer.contentsTweaker.TypeRegistry
88
object BaseModifier : PatchHandler.Resolver {
99
override fun resolve(node: Node, child: String): Node? {
1010
if (child != "=") return null
11-
if (node !is Node.Modifiable) error("${node.key} is not Modifiable, can't assign")
11+
if (node !is Node.Modifiable<*>) error("${node.key} is not Modifiable, can't assign")
1212
return node.withModifier(child) { json ->
1313
val value = TypeRegistry.resolveType(json, type, elementType, keyType)
1414
beforeModify()
15-
setValue(value)
15+
setValueAny(value)
1616
}
1717
}
1818
}

src/main/kotlin/cf/wayzer/contentsTweaker/resolvers/BlockConsumesResolver.kt

+41-42
Original file line numberDiff line numberDiff line change
@@ -11,55 +11,54 @@ import mindustry.world.consumers.*
1111

1212
object BlockConsumesResolver : PatchHandler.Resolver, TypeRegistry.Resolver {
1313
override fun resolve(node: Node, child: String): Node? {
14-
if (node is Node.Modifiable && node.obj is Array<*> && node.elementType == Consume::class.java) {
15-
val block = ((node.parent as Node.WithObj).obj as? Block) ?: return null
16-
fun modifier(body: Array<Consume>.(JsonValue) -> Array<Consume>) = node.withModifier(child) {
17-
beforeModify()
18-
PatchHandler.registerAfterHandler(node.key) {
19-
block.apply {
20-
consPower = consumers.filterIsInstance<ConsumePower>().firstOrNull()
21-
optionalConsumers = consumers.filter { it.optional && !it.ignore() }.toTypedArray()
22-
nonOptionalConsumers = consumers.filter { !it.optional && !it.ignore() }.toTypedArray()
23-
updateConsumers = consumers.filter { it.update && !it.ignore() }.toTypedArray()
24-
hasConsumers = consumers.isNotEmpty()
25-
itemFilter.fill(false)
26-
liquidFilter.fill(false)
27-
consumers.forEach { it.apply(this) }
28-
setBars()
29-
}
14+
if (node !is Node.Modifiable<*> || !Array<Consume>::class.java.isAssignableFrom(node.type))
15+
return null
16+
val block = ((node.parent as Node.WithObj<*>).obj as? Block) ?: return null
17+
fun modifier(body: Array<Consume>.(JsonValue) -> Array<Consume>) = node.withModifier(child) { v ->
18+
beforeModify()
19+
PatchHandler.registerAfterHandler(key) {
20+
block.apply {
21+
consPower = consumers.filterIsInstance<ConsumePower>().firstOrNull()
22+
optionalConsumers = consumers.filter { it.optional && !it.ignore() }.toTypedArray()
23+
nonOptionalConsumers = consumers.filter { !it.optional && !it.ignore() }.toTypedArray()
24+
updateConsumers = consumers.filter { it.update && !it.ignore() }.toTypedArray()
25+
hasConsumers = consumers.isNotEmpty()
26+
itemFilter.fill(false)
27+
liquidFilter.fill(false)
28+
consumers.forEach { it.apply(this) }
29+
setBars()
3030
}
31-
@Suppress("UNCHECKED_CAST") val obj = node.obj as Array<Consume>
32-
setValue(obj.body(it))
3331
}
34-
return when (child) {
35-
"clearItems" -> modifier { filterNot { it is ConsumeItems || it is ConsumeItemFilter }.toTypedArray() }
36-
"item" -> modifier { this + ConsumeItems(arrayOf(ItemStack(TypeRegistry.resolve(it), 1))) }
37-
"items" -> modifier { this + TypeRegistry.resolve<ConsumeItems>(it) }
38-
"itemCharged" -> modifier { this + TypeRegistry.resolve<ConsumeItemCharged>(it) }
39-
"itemFlammable" -> modifier { this + TypeRegistry.resolve<ConsumeItemFlammable>(it) }
40-
"itemRadioactive" -> modifier { this + TypeRegistry.resolve<ConsumeItemRadioactive>(it) }
41-
"itemExplosive" -> modifier { this + TypeRegistry.resolve<ConsumeItemExplosive>(it) }
42-
"itemExplode" -> modifier { this + TypeRegistry.resolve<ConsumeItemExplode>(it) }
43-
44-
"clearLiquids" -> modifier { filterNot { it is ConsumeLiquidBase || it is ConsumeLiquids }.toTypedArray() }
45-
"liquid" -> modifier { this + TypeRegistry.resolve<ConsumeLiquid>(it) }
46-
"liquids" -> modifier { this + TypeRegistry.resolve<ConsumeLiquids>(it) }
47-
"liquidFlammable" -> modifier { this + TypeRegistry.resolve<ConsumeLiquidFlammable>(it) }
48-
"coolant" -> modifier { this + TypeRegistry.resolve<ConsumeCoolant>(it) }
32+
@Suppress("UNCHECKED_CAST")
33+
setValueAny((obj as Array<Consume>).body(v))
34+
}
35+
return when (child) {
36+
"clearItems" -> modifier { filterNot { it is ConsumeItems || it is ConsumeItemFilter }.toTypedArray() }
37+
"item" -> modifier { this + ConsumeItems(arrayOf(ItemStack(TypeRegistry.resolve(it), 1))) }
38+
"items" -> modifier { this + TypeRegistry.resolve<ConsumeItems>(it) }
39+
"itemCharged" -> modifier { this + TypeRegistry.resolve<ConsumeItemCharged>(it) }
40+
"itemFlammable" -> modifier { this + TypeRegistry.resolve<ConsumeItemFlammable>(it) }
41+
"itemRadioactive" -> modifier { this + TypeRegistry.resolve<ConsumeItemRadioactive>(it) }
42+
"itemExplosive" -> modifier { this + TypeRegistry.resolve<ConsumeItemExplosive>(it) }
43+
"itemExplode" -> modifier { this + TypeRegistry.resolve<ConsumeItemExplode>(it) }
4944

50-
"clearPower" -> modifier { filterNot { it is ConsumePower }.toTypedArray() }
51-
"power" -> modifier {
52-
this.filterNot { c -> c is ConsumePower }.toTypedArray() + TypeRegistry.resolve<ConsumePower>(it)
53-
}
45+
"clearLiquids" -> modifier { filterNot { it is ConsumeLiquidBase || it is ConsumeLiquids }.toTypedArray() }
46+
"liquid" -> modifier { this + TypeRegistry.resolve<ConsumeLiquid>(it) }
47+
"liquids" -> modifier { this + TypeRegistry.resolve<ConsumeLiquids>(it) }
48+
"liquidFlammable" -> modifier { this + TypeRegistry.resolve<ConsumeLiquidFlammable>(it) }
49+
"coolant" -> modifier { this + TypeRegistry.resolve<ConsumeCoolant>(it) }
5450

55-
"powerBuffered" -> modifier {
56-
this.filterNot { c -> c is ConsumePower }.toTypedArray() + ConsumePower(0f, it.asFloat(), true)
57-
}
51+
"clearPower" -> modifier { filterNot { it is ConsumePower }.toTypedArray() }
52+
"power" -> modifier {
53+
this.filterNot { c -> c is ConsumePower }.toTypedArray() + TypeRegistry.resolve<ConsumePower>(it)
54+
}
5855

59-
else -> null
56+
"powerBuffered" -> modifier {
57+
this.filterNot { c -> c is ConsumePower }.toTypedArray() + ConsumePower(0f, it.asFloat(), true)
6058
}
59+
60+
else -> null
6161
}
62-
return null
6362
}
6463

6564
override fun <T : Any> resolveType(json: JsonValue, type: Class<T>?, elementType: Class<*>?, keyType: Class<*>?): T? {

src/main/kotlin/cf/wayzer/contentsTweaker/resolvers/ObjectMapItemNode.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ import cf.wayzer.contentsTweaker.PatchHandler.Node
77
import cf.wayzer.contentsTweaker.PatchHandler.withModifier
88
import cf.wayzer.contentsTweaker.TypeRegistry
99

10-
class ObjectMapItemNode(override val parent: Node, val mapKey: Any?, key: String) : Node(key), Node.Modifiable {
10+
class ObjectMapItemNode(override val parent: Node, val mapKey: Any?, key: String) : Node(key), Node.Modifiable<Any?> {
1111
@Suppress("UNCHECKED_CAST")
12-
private val map = ((parent as WithObj).obj as ObjectMap<Any, Any>)
13-
override val type: Class<*>?
14-
get() = (parent as WithObj).elementType ?: obj?.javaClass
12+
private val map = ((parent as WithObj<*>).obj as ObjectMap<Any, Any>)
13+
override val type: Class<*>
14+
get() = (parent as WithObj<*>).elementType ?: obj?.javaClass ?: Any::class.java
1515

1616
override fun setValue(value: Any?) {
1717
map.put(mapKey, value)
@@ -36,7 +36,7 @@ class ObjectMapItemNode(override val parent: Node, val mapKey: Any?, key: String
3636

3737
companion object Resolver : PatchHandler.Resolver {
3838
override fun resolve(node: Node, child: String): Node? {
39-
if (node !is WithObj) return null
39+
if (node !is WithObj<*>) return null
4040
val obj = node.obj
4141
if (obj !is ObjectMap<*, *>) return null
4242
val keyType = node.keyType ?: (obj.keys().firstOrNull()?.javaClass)

src/main/kotlin/cf/wayzer/contentsTweaker/resolvers/ReflectNode.kt

+13-9
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,25 @@ import cf.wayzer.contentsTweaker.PatchHandler.Node
66
import java.lang.reflect.Field
77

88

9-
class ReflectNode(override val parent: Node, key: String, val field: Field) : Node(key), Node.Modifiable {
10-
override val obj: Any = field.get((parent as WithObj).obj)
11-
override val type: Class<out Any> get() = this.field.type
12-
private val typeMeta: FieldMetadata by lazy { this.field.let(::FieldMetadata) }
9+
class ReflectNode<T>(override val parent: Node, key: String, val f: Field) : Node(key), Node.Modifiable<T> {
10+
@Suppress("UNCHECKED_CAST")
11+
override val obj: T get() = f.get((parent as WithObj<*>).obj) as T
12+
13+
@Suppress("UNCHECKED_CAST")
14+
override val type: Class<T> get() = this.f.type as Class<T>
15+
private val typeMeta: FieldMetadata by lazy { this.f.let(::FieldMetadata) }
1316
override val elementType: Class<*>? get() = typeMeta.elementType
1417
override val keyType: Class<*>? get() = typeMeta.keyType
1518

1619
override val storeDepth: Int get() = 0
20+
private val bak = obj
1721
override fun doSave() {}//already
1822
override fun doRecover() {
19-
setValue(obj)
23+
setValue(bak)
2024
}
2125

22-
override fun setValue(value: Any?) {
23-
field.set((parent as WithObj).obj, value)
26+
override fun setValue(value: T) {
27+
f.set((parent as WithObj<*>).obj, value)
2428
}
2529

2630
companion object Resolver : PatchHandler.Resolver {
@@ -38,11 +42,11 @@ class ReflectNode(override val parent: Node, key: String, val field: Field) : No
3842
}
3943

4044
override fun resolve(node: Node, child: String): Node? {
41-
if (node !is WithObj) return null
45+
if (node !is WithObj<*>) return null
4246
val obj = node.obj ?: return null
4347
val field = kotlin.runCatching { getField(obj, child) }
4448
.getOrNull() ?: return null
45-
return ReflectNode(node, node.subKey(child), field)
49+
return ReflectNode<Any>(node, node.subKey(child), field)
4650
}
4751
}
4852
}

src/main/kotlin/cf/wayzer/contentsTweaker/resolvers/SeqResolver.kt

+19-23
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,25 @@ import cf.wayzer.contentsTweaker.TypeRegistry
88
import mindustry.io.JsonIO
99

1010
object SeqResolver : PatchHandler.Resolver {
11-
class SeqItemNode(override val parent: Node, val index: Int, key: String) : Node(key), Node.Modifiable {
11+
class SeqItemNode<T : Any>(override val parent: Node, val index: Int, key: String) : Node(key), Node.Modifiable<T> {
1212
@Suppress("UNCHECKED_CAST")
13-
private val seq = (parent as WithObj).obj as Seq<Any>
14-
15-
override val obj: Any? = seq.get(index)
16-
override val type: Class<*>?
17-
get() = (parent as WithObj).elementType ?: obj?.javaClass
13+
private val seq = (parent as WithObj<*>).obj as Seq<T>
14+
override val obj: T get() = seq.get(index)
15+
override val type: Class<*> get() = ((parent as WithObj<*>).elementType ?: obj.javaClass)
1816
override val storeDepth: Int get() = 0
17+
private val bak = obj
1918
override fun doSave() {}
20-
override fun doRecover() = setValue(obj)
19+
override fun doRecover() = setValue(bak)
2120

22-
override fun setValue(value: Any?) {
21+
override fun setValue(value: T) {
2322
seq.set(index, value)
2423
}
2524
}
2625

27-
class AsModifiable(override val parent: Node, override val obj: Seq<*>, val deepCopy: Boolean) : Node(parent.key), Node.Modifiable {
28-
private lateinit var backup: Seq<*>
29-
override val type: Class<*> = Seq::class.java
30-
override val elementType: Class<*>? = (parent as WithObj).elementType ?: obj.firstOrNull()?.javaClass
26+
class AsModifiable<T : Any>(override val parent: Node, override val obj: Seq<T>, val deepCopy: Boolean) : Node(parent.key), Node.Modifiable<Seq<T>> {
27+
private lateinit var backup: Seq<T>
28+
override val type: Class<Seq<*>> = Seq::class.java
29+
override val elementType: Class<*>? = (parent as WithObj<*>).elementType ?: obj.firstOrNull()?.javaClass
3130

3231
override val storeDepth: Int get() = if (deepCopy) Int.MAX_VALUE else 0
3332
override fun doSave() {
@@ -41,41 +40,38 @@ object SeqResolver : PatchHandler.Resolver {
4140
setValue(backup)
4241
}
4342

44-
override fun setValue(value: Any?) {
45-
@Suppress("UNCHECKED_CAST")
46-
val value2 = value as Seq<out Nothing>?
43+
override fun setValue(value: Seq<T>) {
4744
obj.clear()
48-
if (value2 != null)
49-
obj.addAll(value2)
45+
obj.addAll(value)
5046
}
5147
}
5248

5349
override fun resolve(node: Node, child: String): Node? {
54-
if (node !is Node.WithObj) return null
50+
if (node !is Node.WithObj<*>) return null
5551
val obj = node.obj
5652
if (obj !is Seq<*>) return null
5753
//通过数字索引
58-
child.toIntOrNull()?.let { return SeqItemNode(node, it, node.subKey(child)) }
54+
child.toIntOrNull()?.let { return SeqItemNode<Any>(node, it, node.subKey(child)) }
5955
when (child) {
6056
"+=" -> {
61-
if (node !is Node.Modifiable) error("${node.key} is Seq<*>, but not Modifiable, try use `asModifiable`")
57+
if (node !is Node.Modifiable<*>) error("${node.key} is Seq<*>, but not Modifiable, try use `asModifiable`")
6258
return node.withModifier(child) { json ->
6359
val value = TypeRegistry.resolve<Seq<Any>>(json, elementType)
6460
beforeModify()
6561
@Suppress("UNCHECKED_CAST")
66-
setValue(obj.copy().addAll(value as Seq<out Nothing>))
62+
setValueAny(obj.copy().addAll(value as Seq<out Nothing>))
6763
}
6864
}
6965
//不支持-运算符,容易导致索引型的解析错误或者失败
7066

7167
"+" -> {
72-
if (node !is Node.Modifiable) error("${node.key} is Seq<*>, but not Modifiable, try use `asModifiable`")
68+
if (node !is Node.Modifiable<*>) error("${node.key} is Seq<*>, but not Modifiable, try use `asModifiable`")
7369
return node.withModifier(child) { json ->
7470
val value = TypeRegistry.resolveType(json, elementType)
7571
beforeModify()
7672
@Suppress("UNCHECKED_CAST")
7773
val parentSeq = obj as Seq<Any>
78-
setValue(parentSeq.copy().add(value))
74+
setValueAny(parentSeq.copy().add(value))
7975
}
8076
}
8177

src/main/kotlin/cf/wayzer/contentsTweaker/resolvers/UIExtNode.kt

+6-4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import arc.scene.ui.layout.Table
1414
import arc.util.Align
1515
import cf.wayzer.contentsTweaker.PatchHandler
1616
import cf.wayzer.contentsTweaker.PatchHandler.withModifier
17+
import mindustry.Vars
1718
import mindustry.gen.Call
1819
import mindustry.ui.Styles
1920

@@ -50,7 +51,7 @@ import mindustry.ui.Styles
5051
* }
5152
* ```
5253
*/
53-
open class UIExtNode(override val parent: PatchHandler.Node, key: String, val uiNode: Element) : PatchHandler.Node(key), PatchHandler.Node.WithObj {
54+
open class UIExtNode(override val parent: PatchHandler.Node, key: String, val uiNode: Element) : PatchHandler.Node(key), PatchHandler.Node.WithObj<Element> {
5455
private var tableCell: Cell<Element>? = null
5556
val children = mutableMapOf<String, UIExtNode>()
5657
override val obj get() = uiNode
@@ -157,7 +158,7 @@ open class UIExtNode(override val parent: PatchHandler.Node, key: String, val ui
157158
else -> null
158159
}
159160

160-
object Root : UIExtNode(PatchHandler.Node.Root, "uiExt.", Core.scene.root), Storable {
161+
object Root : UIExtNode(PatchHandler.Node.Root, "uiExt.", Core.scene.root ?: Element()), Storable {
161162
override val storeDepth: Int = Int.MAX_VALUE
162163
override fun doSave() {}
163164
override fun doRecover() {
@@ -167,15 +168,16 @@ open class UIExtNode(override val parent: PatchHandler.Node, key: String, val ui
167168
}
168169

169170
companion object Resolver : PatchHandler.Resolver {
170-
val alignMap = Align::class.java.declaredFields.associate { it.name to it.getInt(null) }
171-
val stylesMap = Styles::class.java.declaredFields.associate { it.name to it.get(null)!! }
171+
val alignMap by lazy { Align::class.java.declaredFields.associate { it.name to it.getInt(null) } }
172+
val stylesMap by lazy { Styles::class.java.declaredFields.associate { it.name to it.get(null)!! } }
172173
fun createUIElement(type: String): Element = when (type) {
173174
"Table" -> Table()
174175
"Label" -> Label("")
175176
else -> error("TODO: not support Element: $type")
176177
}
177178

178179
override fun resolve(node: PatchHandler.Node, child: String): PatchHandler.Node? {
180+
if (Vars.headless) return null
179181
if (node == PatchHandler.Node.Root && child == "uiExt") return Root
180182
return null
181183
}

0 commit comments

Comments
 (0)