Skip to content

Commit 2187c8d

Browse files
committed
Rare Candy is online!
1 parent b182bd3 commit 2187c8d

File tree

11 files changed

+67
-86
lines changed

11 files changed

+67
-86
lines changed

build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ subprojects {
3737
maven("https://jitpack.io")
3838
maven("https://maven.generations.gg/snapshots")
3939
maven("https://maven.generations.gg/releases")
40+
maven("https://generationsmaven.firstdark.dev/snapshots")
41+
maven("https://generationsmaven.firstdark.dev/releases")
42+
4043
maven("https://pkgs.dev.azure.com/djtheredstoner/DevAuth/_packaging/public/maven/v1")
4144
maven("https://cursemaven.com").content { includeGroup("curse.maven") }
4245
maven("https://api.modrinth.com/maven").content { includeGroup("maven.modrinth") }

common/src/main/java/generations/gg/generations/core/generationscore/common/GenerationsDataProvider.kt

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,8 @@ import com.cobblemon.mod.common.api.Priority
44
import com.cobblemon.mod.common.api.data.DataProvider
55
import com.cobblemon.mod.common.api.data.DataRegistry
66
import com.cobblemon.mod.common.platform.events.PlatformEvents
7-
import com.cobblemon.mod.common.util.ifClient
87
import com.cobblemon.mod.common.util.server
9-
import dev.architectury.platform.Platform
10-
import dev.architectury.utils.Env
11-
import dev.architectury.utils.EnvExecutor
12-
import generations.gg.generations.core.generationscore.common.client.CompiledModelLoader
138
import generations.gg.generations.core.generationscore.common.network.packets.S2CUnlockReloadPacket
14-
import generations.gg.generations.core.generationscore.common.world.shop.ShopPresets
15-
import generations.gg.generations.core.generationscore.common.world.shop.Shops
169
import net.minecraft.resources.ResourceLocation
1710
import net.minecraft.server.level.ServerPlayer
1811
import net.minecraft.server.packs.PackType
@@ -38,7 +31,7 @@ class GenerationsDataProvider : DataProvider {
3831
S2CUnlockReloadPacket().sendToPlayer(it.player)
3932
}
4033

41-
// ifClient { TODO: MOve to Generat
34+
// ifClient {
4235
// GenerationsCore.implementation.registerResourceReloader(GenerationsCore.id("client_resources"), SimpleResourceReloader(PackType.CLIENT_RESOURCES), PackType.CLIENT_RESOURCES, emptyList())
4336
// GenerationsCore.implementation.registerResourceReloader(GenerationsCore.id("model_registry"), CompiledModelLoader(), PackType.CLIENT_RESOURCES, emptyList())
4437
// }

common/src/main/java/generations/gg/generations/core/generationscore/common/client/GenerationsCoreClient.kt

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@ import com.mojang.blaze3d.systems.RenderSystem
1515
import com.mojang.blaze3d.vertex.BufferUploader
1616
import com.mojang.blaze3d.vertex.PoseStack
1717
import com.mojang.blaze3d.vertex.VertexConsumer
18+
import dev.architectury.registry.ReloadListenerRegistry
1819
import dev.architectury.registry.item.ItemPropertiesRegistry
1920
import dev.architectury.registry.menu.MenuRegistry
2021
import generations.gg.generations.core.generationscore.common.GenerationsCore
2122
import generations.gg.generations.core.generationscore.common.GenerationsCore.LOGGER
23+
import generations.gg.generations.core.generationscore.common.GenerationsDataProvider
24+
import generations.gg.generations.core.generationscore.common.GenerationsDataProvider.SimpleResourceReloader
2225
import generations.gg.generations.core.generationscore.common.client.model.GenerationsClientMolangFunctions
2326
import generations.gg.generations.core.generationscore.common.client.model.RareCandyBone
2427
import generations.gg.generations.core.generationscore.common.client.model.RunnableKeybind
@@ -67,6 +70,7 @@ import net.minecraft.client.renderer.entity.EntityRendererProvider
6770
import net.minecraft.client.renderer.entity.ThrownItemRenderer
6871
import net.minecraft.core.BlockPos
6972
import net.minecraft.resources.ResourceLocation
73+
import net.minecraft.server.packs.PackType
7074
import net.minecraft.util.Mth
7175
import net.minecraft.world.InteractionHand
7276
import net.minecraft.world.entity.Entity
@@ -82,10 +86,11 @@ import net.minecraft.world.level.block.state.properties.WoodType
8286
import net.minecraft.world.phys.Vec3
8387
import net.minecraft.world.phys.shapes.CollisionContext
8488
import net.minecraft.world.phys.shapes.VoxelShape
89+
import org.joml.Matrix4f
90+
import org.joml.Quaternionf
8591
import org.joml.Vector4f
8692
import org.lwjgl.glfw.GLFW
8793
import java.io.File
88-
import java.util.function.BiConsumer
8994
import java.util.function.Function
9095
import java.util.function.Supplier
9196

@@ -124,7 +129,9 @@ object GenerationsCoreClient {
124129
// CobblemonBuiltinItemRendererRegistry.INSTANCE.register(GenerationsItems.ENTEI_STATUE.get(), renderer);
125130
// CobblemonBuiltinItemRendererRegistry.INSTANCE.register(CobblemonItems.POKEMON_MODEL, renderer);
126131

127-
// ReloadListenerRegistry.register(PackType.CLIENT_RESOURCES, (ResourceManagerReloadListener) Pipelines::onInitialize);
132+
133+
GenerationsCore.implementation.registerResourceReloader(GenerationsCore.id("model_registry"), CompiledModelLoader(), PackType.CLIENT_RESOURCES, emptyList())
134+
128135
setupClient(minecraft)
129136

130137
GenerationsClientMolangFunctions.addAnimationFunctions()
@@ -444,7 +451,7 @@ object GenerationsCoreClient {
444451
x: Double,
445452
y: Double,
446453
z: Double,
447-
color: Vector4f
454+
color: Vector4f,
448455
) {
449456
val pose = poseStack.last()
450457
// Create the vertex consumer shape by creating every edge.
@@ -472,7 +479,7 @@ object GenerationsCoreClient {
472479
vertexConsumer: VertexConsumer,
473480
blockPos: BlockPos,
474481
camPos: Vec3,
475-
color: Vector4f
482+
color: Vector4f,
476483
) {
477484
val pose = poseStack.last()
478485
val pos = pos2 - pos1
@@ -505,7 +512,7 @@ object GenerationsCoreClient {
505512
camera: Camera,
506513
blockPos: BlockPos,
507514
blockState: BlockState,
508-
color: Vector4f
515+
color: Vector4f,
509516
) {
510517
val pos = camera.position
511518
renderShape(

common/src/main/java/generations/gg/generations/core/generationscore/common/client/GenerationsTextureLoader.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ object GenerationsTextureLoader : ITextureLoader() {
6363
}
6464
}
6565

66+
System.out.println()
67+
6668
// RARE_CANDY.listMatchingResources(manager).values.forEach { resouce ->
6769
// resouce.openAsReader().use { GsonHelper.fromJson(gson, it, RARE_CANDY_TYPE) }.forEach { (key, value) ->
6870
// register(key, SimpleTextureEnhanced(value.asResource().let { "${it.namespace}:textures/${it.path}.png" }.asResource()))

common/src/main/java/generations/gg/generations/core/generationscore/common/client/render/block/entity/GeneralUseBlockEntityRenderer.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package generations.gg.generations.core.generationscore.common.client.render.block.entity
22

3+
import com.mojang.blaze3d.systems.RenderSystem
34
import com.mojang.blaze3d.vertex.PoseStack
45
import generations.gg.generations.core.generationscore.common.client.model.ModelContextProviders.FrameProvider
56
import generations.gg.generations.core.generationscore.common.client.model.ModelContextProviders.TintProvider
@@ -26,7 +27,7 @@ open class GeneralUseBlockEntityRenderer<T : ModelProvidingBlockEntity>(ctx: Blo
2627
packedLight: Int,
2728
packedOverlay: Int
2829
) {
29-
blockEntity.blockState.block.instanceOrNull<GenericModelBlock<*>>()?.takeIf { !it.canRender(blockEntity) } ?: return
30+
blockEntity.blockState.block.instanceOrNull<GenericModelBlock<*>>()?.takeIf { it.canRender(blockEntity) } ?: return
3031

3132
if (blockEntity.objectInstance == null) {
3233
val amount = instanceAmount()
@@ -71,6 +72,8 @@ open class GeneralUseBlockEntityRenderer<T : ModelProvidingBlockEntity>(ctx: Blo
7172
}
7273

7374
instance.transformationMatrix().set(stack.last().pose())
75+
// instance.viewMatrix().set(RenderSystem.getModelViewMatrix())
76+
7477
(instance as BlockObjectInstance).light = packedLight
7578
if (blockEntity is TintProvider) instance.tint = blockEntity.tint
7679
model.render(instance, buffersource)

common/src/main/java/generations/gg/generations/core/generationscore/common/client/render/rarecandy/CompiledModel.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package generations.gg.generations.core.generationscore.common.client.render.rar
22

33
import com.mojang.blaze3d.systems.RenderSystem
44
import com.mojang.blaze3d.vertex.BufferUploader
5+
import dev.architectury.event.events.client.ClientTooltipEvent.Render
56
import generations.gg.generations.core.generationscore.common.GenerationsCore
67
import generations.gg.generations.core.generationscore.common.client.render.rarecandy.loading.GenerationsModelLoader
78
import generations.gg.generations.core.generationscore.common.client.render.rarecandy.loading.VanilaRenderModel

common/src/main/java/generations/gg/generations/core/generationscore/common/client/render/rarecandy/Pipelines.kt

Lines changed: 34 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import gg.generations.rarecandy.renderer.animation.AnimationController
1616
import gg.generations.rarecandy.renderer.animation.Transform
1717
import gg.generations.rarecandy.renderer.loading.ITexture
1818
import gg.generations.rarecandy.renderer.model.material.Material
19+
import gg.generations.rarecandy.renderer.model.material.MaterialValues
1920
import gg.generations.rarecandy.renderer.model.material.PipelineRegistry
2021
import gg.generations.rarecandy.renderer.pipeline.Pipeline
2122
import gg.generations.rarecandy.renderer.pipeline.UniformUploadContext
@@ -39,6 +40,8 @@ object Pipelines {
3940
)
4041
)
4142
private val ONE = Vector3f(1f, 1f, 1f)
43+
private val ZERO = Vector3f(0f, 0f, 0f)
44+
4245

4346
@JvmField
4447
var REGISTER: Event<Consumer<PipelineRegister>> = EventFactory.createConsumerLoop(
@@ -85,7 +88,7 @@ object Pipelines {
8588
val builder = Pipeline.Builder()
8689
.supplyUniform(
8790
"viewMatrix"
88-
) { ctx: UniformUploadContext -> ctx.uniform().uploadMat4f(ctx.instance().viewMatrix()) }
91+
) { ctx -> ctx.uniform().uploadMat4f(RenderSystem.getModelViewMatrix()) }
8992
.supplyFloatUniform("FogStart") { RenderSystem.getShaderFogStart() }
9093
.supplyFloatUniform("FogEnd") { RenderSystem.getShaderFogEnd() }
9194
.supplyColorArray("FogColor") { RenderSystem.getShaderFogColor() }
@@ -97,7 +100,7 @@ object Pipelines {
97100
.supplyVec2("uvOffset") { it.transform.offset() ?: Transform.DEFAULT_OFFSET }
98101
.supplyVec2("uvScale") { it.transform.scale() ?: Transform.DEFAULT_SCALE }
99102
.supplyTexture("diffuse", 0) {
100-
it.getTextureOrOther("diffuse") { ITextureLoader.instance().nuetralFallback }
103+
it.getTextureOrOther({ it.material.images().diffuse }) { ITextureLoader.instance().nuetralFallback }
101104
}
102105
.configure(::addLight)
103106
.supplyVec3("Light0_Direction") {
@@ -106,7 +109,7 @@ object Pipelines {
106109
.supplyVec3("Light1_Direction") {
107110
RenderSystem.shaderLightDirections[1]
108111
}
109-
.supplyVec3("cobblemonTint") { it.instance.instanceOrNull<CobblemonInstance>()?.tint ?: ONE }
112+
.supplyVec3("cobblemonTint") { it.instance.instanceOrNull<CobblemonInstance>()?.tint?.takeIf { it != ZERO } ?: ONE }
110113
.prePostDraw({ material: Material ->
111114
if (material.cullType() != CullType.None) {
112115
RenderSystem.enableCull()
@@ -178,10 +181,12 @@ object Pipelines {
178181
.configure(::baseColors)
179182
.configure(::emissionColors)
180183
.supplyTexture("layer", 3) {
181-
ctx -> ctx.getTexture("layer").takeIf { !ctx.isStatueMaterial } ?: ITextureLoader.instance().darkFallback
184+
it.getTextureOrOther({ it.material.images().layer}) {
185+
ITextureLoader.instance().darkFallback
186+
}
182187
}
183188
.supplyTexture("mask", 4) {
184-
it.getTextureOrOther("mask") {
189+
it.getTextureOrOther({ it.material.images().mask}) {
185190
ITextureLoader.instance().darkFallback
186191
}
187192
}
@@ -190,12 +195,10 @@ object Pipelines {
190195
private fun Pipeline.Builder.masked(): Pipeline.Builder {
191196
return this
192197
.supplyTexture("mask", 3) {
193-
it.getTextureOrOther("mask") { ITextureLoader.instance().darkFallback }
198+
it.getTextureOrOther({ it.material.images().mask }) { ITextureLoader.instance().darkFallback }
194199
}
195200
.supplyVec3("color") {
196-
var color = it.instance.instanceOrNull<TintProvider>()?.getTint() ?: it.getColorValue("color")
197-
198-
201+
var color = it.instance.instanceOrNull<TintProvider>()?.getTint() ?: it.material.values().baseColor1
199202
color
200203
}
201204
}
@@ -220,65 +223,32 @@ object Pipelines {
220223
}
221224

222225
private fun emissionColors(builder: Pipeline.Builder) = builder
223-
.supplyVec3("emiColor1") {
224-
it.getColorValue("emiColor1")
225-
}
226-
.supplyVec3("emiColor2") {
227-
it.getColorValue("emiColor2")
228-
}
229-
.supplyVec3("emiColor3") {
230-
it.getColorValue("emiColor3")
231-
}
232-
.supplyVec3("emiColor4") {
233-
it.getColorValue("emiColor4")
234-
}
226+
.supplyVec3("emiColor1") { it.takeIf { !it.isStatueMaterial }?.material?.values()?.emiColor1 ?: ONE }
227+
.supplyVec3("emiColor2") { it.takeIf { !it.isStatueMaterial }?.material?.values()?.emiColor2 ?: ONE }
228+
.supplyVec3("emiColor3") { it.takeIf { !it.isStatueMaterial }?.material?.values()?.emiColor3 ?: ONE }
229+
.supplyVec3("emiColor4") { it.takeIf { !it.isStatueMaterial }?.material?.values()?.emiColor4 ?: ONE }
235230
.supplyVec3("emiColor5") {
236-
it.instance.instanceOrNull<TintProvider>()?.tint ?: it.getColorValue("emiColor5")
237-
}
238-
.supplyFloatUniform("emiIntensity1") {
239-
it.getFloatValue("emiIntensity1")
240-
}
241-
.supplyFloatUniform("emiIntensity2") {
242-
it.getFloatValue("emiIntensity2")
243-
}
244-
.supplyFloatUniform("emiIntensity3") {
245-
it.getFloatValue("emiIntensity3")
246-
}
247-
.supplyFloatUniform("emiIntensity4") {
248-
it.getFloatValue("emiIntensity4")
249-
}
250-
.supplyFloatUniform("emiIntensity5") {
251-
it.getFloatValue("emiIntensity5", 1.0f)
231+
it.instance.instanceOrNull<TintProvider>()?.tint ?: it.material.values().emiColor5
252232
}
233+
.supplyFloatUniform("emiIntensity1") { it.takeIf { !it.isStatueMaterial }?.material?.values()?.emiIntensity1 ?: 0.0f }
234+
.supplyFloatUniform("emiIntensity2") { it.takeIf { !it.isStatueMaterial }?.material?.values()?.emiIntensity2 ?: 0.0f }
235+
.supplyFloatUniform("emiIntensity3") { it.takeIf { !it.isStatueMaterial }?.material?.values()?.emiIntensity3 ?: 0.0f }
236+
.supplyFloatUniform("emiIntensity4") { it.takeIf { !it.isStatueMaterial }?.material?.values()?.emiIntensity4 ?: 0.0f }
237+
.supplyFloatUniform("emiIntensity5") { it.takeIf { !it.isStatueMaterial }?.material?.values()?.emiIntensity5 ?: 1.0f }
253238

254239

255-
private fun baseColors(builder: Pipeline.Builder) = builder
256-
.supplyVec3("baseColor1") {
257-
it.getColorValue("baseColor1")
258-
}
259-
.supplyVec3("baseColor2") {
260-
it.getColorValue("baseColor2")
261-
}
262-
.supplyVec3("baseColor3") {
263-
it.getColorValue("baseColor3")
264-
}
265-
.supplyVec3("baseColor4") {
266-
it.getColorValue("baseColor4")
267-
}
268-
.supplyVec3("baseColor5") {
269-
it.getColorValue("baseColor5")
270-
}
271-
272240

273-
private fun UniformUploadContext.getColorValue(id: String): Vector3f {
274-
return (if (!this.isStatueMaterial) this.value<Vector3f>(id) else null) ?: ONE
275-
}
276-
277-
private fun UniformUploadContext.getFloatValue(id: String, value: Float = 0.0f): Float {
278-
return (if (!this.isStatueMaterial) this.value<Float>(id) else null) ?: value
279-
}
241+
private fun baseColors(builder: Pipeline.Builder) = builder
242+
.supplyVec3("baseColor1", { ctx -> ctx.takeIf { !it.isStatueMaterial }?.material?.values()?.baseColor1 ?: ONE } )
243+
.supplyVec3("baseColor2", { ctx -> ctx.takeIf { !it.isStatueMaterial }?.material?.values()?.baseColor2 ?: ONE } )
244+
.supplyVec3("baseColor3", { ctx -> ctx.takeIf { !it.isStatueMaterial }?.material?.values()?.baseColor3 ?: ONE } )
245+
.supplyVec3("baseColor4", { ctx -> ctx.takeIf { !it.isStatueMaterial }?.material?.values()?.baseColor4 ?: ONE } )
246+
.supplyVec3("baseColor5", { ctx -> ctx.takeIf { !it.isStatueMaterial }?.material?.values()?.baseColor5 ?: ONE } )
280247

281-
private fun UniformUploadContext.getTextureOrOther(name: String, function: () -> ITexture): ITexture = this.getTexture(name)?.takeUnless { texture -> this.isStatueMaterial || texture === GenerationsTextureLoader.MissingTextureProxy } ?: function.invoke()
248+
private fun UniformUploadContext.getTextureOrOther(
249+
function: (UniformUploadContext) -> String?,
250+
supplier: () -> ITexture
251+
): ITexture = GenerationsTextureLoader.getTexture(function.invoke(this))?.takeUnless { texture -> this.isStatueMaterial || texture === GenerationsTextureLoader.MissingTextureProxy } ?: supplier.invoke()
282252

283253
private fun addLight(builder: Pipeline.Builder) {
284254
builder
@@ -287,8 +257,8 @@ object Pipelines {
287257
val light = (ctx.instance() as BlockLightValueProvider).light
288258
ctx.uniform().upload2i(light and 0xFFFF, light shr 16 and 0xFFFF)
289259
}
290-
.supplyTexture("emission", 2) { it.getTextureOrOther("emission") { ITextureLoader.instance().darkFallback } }
291-
.supplyBooleanUniform("useLight") { it.value<Boolean>("useLight") ?: true }
260+
.supplyTexture("emission", 2) { it.getTextureOrOther({ it.material.images().emission }) { ITextureLoader.instance().darkFallback } }
261+
.supplyBooleanUniform("useLight") { it.material.values().useLight }
292262
}
293263

294264

@@ -381,10 +351,6 @@ private fun Pipeline.Builder.supplyFloatUniform(name: String, function: (Uniform
381351
return this.supplyUniform(name) { it.uniform.uploadFloat(function.invoke(it))}
382352
}
383353

384-
private inline fun <reified T> UniformUploadContext.value(name: String): T? {
385-
return this.getValue(name).instanceOrNull<T>()
386-
}
387-
388354
private fun Pipeline.Builder.supplyEnumUniform(name: String, value: Enum<*>): Pipeline.Builder = this.supplyInt(name) { value.ordinal }
389355

390356
private fun Pipeline.Builder.supplyInt(name: String, function: () -> Int): Pipeline.Builder = this.also { this.supplyUniform(name) { it.uniform.uploadInt(function.invoke()) } }

common/src/main/java/generations/gg/generations/core/generationscore/common/client/render/rarecandy/loading/VanilaRenderModel.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package generations.gg.generations.core.generationscore.common.client.render.rarecandy.loading;
22

33
import com.mojang.blaze3d.vertex.VertexConsumer;
4+
import generations.gg.generations.core.generationscore.common.client.GenerationsTextureLoader;
45
import generations.gg.generations.core.generationscore.common.client.model.ModelContextProviders;
56
import generations.gg.generations.core.generationscore.common.client.render.rarecandy.BlockLightValueProvider;
67
import generations.gg.generations.core.generationscore.common.client.render.rarecandy.ITextureWithResourceLocation;
@@ -125,7 +126,7 @@ public <T extends RenderObject> void render(ObjectInstance instance, T object, M
125126
if (!object.shouldRender(instance)) {
126127

127128
Material material = object.getMaterial(instance.variant());
128-
var texture = material.getDiffuseTexture();
129+
var texture = GenerationsTextureLoader.INSTANCE.getTexture(material.images().getDiffuse());
129130

130131
if(texture instanceof ITextureWithResourceLocation textureWithResourceLocation) {
131132
Transform transform = object.getTransform(instance.variant());

common/src/main/java/generations/gg/generations/core/generationscore/common/client/render/rarecandy/loading/VanillaModelLoader.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package generations.gg.generations.core.generationscore.common.client.render.rarecandy.loading;
22

3-
import gg.generations.rarecandy.assimp.*;
43
import gg.generations.rarecandy.pokeutils.*;
54
import gg.generations.rarecandy.renderer.animation.Animation;
65
import gg.generations.rarecandy.renderer.animation.Skeleton;
@@ -14,7 +13,11 @@
1413
import org.joml.Matrix4f;
1514
import org.joml.Quaternionf;
1615
import org.joml.Vector3f;
16+
import org.lwjgl.BufferUtils;
17+
import org.lwjgl.assimp.*;
18+
import org.lwjgl.system.MemoryUtil;
1719

20+
import java.nio.ByteBuffer;
1821
import java.util.*;
1922
import java.util.function.Supplier;
2023
import java.util.stream.IntStream;

fabric/src/main/java/generations/gg/generations/core/generationscore/fabric/client/GenerationsCoreClientFabric.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ class GenerationsCoreClientFabric : ClientModInitializer {
6464
)
6565
})
6666

67-
WorldRenderEvents.AFTER_ENTITIES.register(AfterEntities { context: WorldRenderContext -> renderRareCandy(context.world()) })
67+
// WorldRenderEvents.AFTER_SETUP.register { GenerationsCoreClient.updateViewMatrix() }
68+
69+
WorldRenderEvents.AFTER_ENTITIES.register { context: WorldRenderContext -> renderRareCandy(context.world()) }
6870

6971
GenerationsFabricNetwork.registerClientHandlers()
7072

0 commit comments

Comments
 (0)