Skip to content

Commit 58a89d0

Browse files
Version 1.3.8.1
1 parent 2d2e490 commit 58a89d0

File tree

18 files changed

+264
-90
lines changed

18 files changed

+264
-90
lines changed

changelog/release-1.3.8.1.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Title: Bug Patch
2+
Summary: Minor bug fixes
3+
4+
## Improvements
5+
- Improved "Add Friend" modal to work regardless of Mojang service availability

elementa/layoutdsl/src/main/kotlin/gg/essential/gui/effects/GradientEffect.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class GradientEffect(
9292
vertSource,
9393
fragSource,
9494
).apply {
95-
blendState = BlendState.NORMAL
95+
blendState = BlendState.ALPHA
9696
depthTest = URenderPipeline.DepthTest.Always
9797
}.build()
9898

@@ -101,7 +101,7 @@ class GradientEffect(
101101
UGraphics.DrawMode.QUADS,
102102
UGraphics.CommonVertexFormats.POSITION_COLOR,
103103
).apply {
104-
blendState = BlendState.NORMAL
104+
blendState = BlendState.ALPHA
105105
depthTest = URenderPipeline.DepthTest.Always
106106
}.build()
107107
}

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ minecraftVersion=11202
1010
# TODO remove once upgrading to Loom 1.10
1111
# fabric-api 1.21.5 was built with Loom 1.10, seems to work well enough in dev with our current 1.7 though
1212
loom.ignoreDependencyLoomVersionValidation=true
13-
version=1.3.8
13+
version=1.3.8.1

gradle/libs.versions.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[versions]
2-
universalcraft = "401"
3-
elementa = "704"
2+
universalcraft = "406"
3+
elementa = "708"
44
vigilance = "306"
55
mixinextras = "0.4.0"
66

gui/essential/src/main/java/gg/essential/util/UuidNameLookup.java

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,18 @@
1111
*/
1212
package gg.essential.util;
1313

14+
import gg.essential.connectionmanager.common.packet.Packet;
15+
import gg.essential.connectionmanager.common.packet.relationships.ClientLookupUuidByNamePacket;
16+
import gg.essential.connectionmanager.common.packet.relationships.ServerLookupUuidByNameResponsePacket;
1417
import gg.essential.elementa.state.BasicState;
1518
import gg.essential.gui.common.ReadOnlyState;
1619
import gg.essential.gui.elementa.state.v2.State;
1720
import gg.essential.lib.gson.Gson;
1821
import gg.essential.lib.gson.JsonElement;
1922
import gg.essential.lib.gson.JsonObject;
2023
import gg.essential.lib.gson.JsonParser;
24+
import gg.essential.network.CMConnection;
25+
import kotlin.coroutines.EmptyCoroutineContext;
2126
import kotlinx.coroutines.Dispatchers;
2227
import okhttp3.Request;
2328
import okhttp3.Response;
@@ -101,27 +106,41 @@ public static CompletableFuture<String> getName(UUID uuid) {
101106
}
102107

103108
public static CompletableFuture<UUID> getUUID(String userName) {
104-
return nameLoadingFutures.computeIfAbsent(userName.toLowerCase(Locale.ROOT), nameLower -> CompletableFuture.supplyAsync(() -> {
105-
try {
106-
Profile profile = fetchProfileFromUsername(nameLower);
107-
UUID loadedUuid = UUID.fromString(
108-
new StringBuilder(profile.getId())
109-
.insert(20, '-')
110-
.insert(16, '-')
111-
.insert(12, '-')
112-
.insert(8, '-')
113-
.toString()
114-
);
115-
uuidLoadingFutures.put(loadedUuid, CompletableFuture.completedFuture(profile.getName()));
116-
return loadedUuid;
117-
} catch (Exception e) {
118-
// Delete cache so we can try again next call
119-
nameLoadingFutures.remove(nameLower);
120-
121-
// Throw exception so future is completed with exception
122-
throw new CompletionException("Failed to load UUID", e);
123-
}
124-
}, asExecutor(Dispatchers.getIO())));
109+
return nameLoadingFutures.computeIfAbsent(userName.toLowerCase(Locale.ROOT), nameLower -> {
110+
CompletableFuture<UUID> future = new CompletableFuture<>();
111+
CMConnection cmConnection = GuiEssentialPlatform.Companion.getPlatform().getCmConnection();
112+
cmConnection.send(new ClientLookupUuidByNamePacket(nameLower), maybeResponse -> {
113+
Packet response = maybeResponse.orElse(null);
114+
if (response instanceof ServerLookupUuidByNameResponsePacket) {
115+
ServerLookupUuidByNameResponsePacket p = (ServerLookupUuidByNameResponsePacket) response;
116+
uuidLoadingFutures.put(p.getUuid(), CompletableFuture.completedFuture(p.getUsername()));
117+
future.complete(p.getUuid());
118+
} else {
119+
Dispatchers.getIO().dispatch(EmptyCoroutineContext.INSTANCE, () -> {
120+
try {
121+
Profile profile = fetchProfileFromUsername(nameLower);
122+
UUID loadedUuid = UUID.fromString(
123+
new StringBuilder(profile.getId())
124+
.insert(20, '-')
125+
.insert(16, '-')
126+
.insert(12, '-')
127+
.insert(8, '-')
128+
.toString()
129+
);
130+
uuidLoadingFutures.put(loadedUuid, CompletableFuture.completedFuture(profile.getName()));
131+
future.complete(loadedUuid);
132+
} catch (Exception e) {
133+
// Delete cache so we can try again next call
134+
nameLoadingFutures.remove(nameLower);
135+
136+
// Throw exception so future is completed with exception
137+
future.completeExceptionally(new CompletionException("Failed to load UUID", e));
138+
}
139+
});
140+
}
141+
});
142+
return future;
143+
});
125144
}
126145

127146
public static void populate(String username, UUID uuid) {

gui/essential/src/main/kotlin/gg/essential/gui/common/MenuButton.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ class MenuButton @JvmOverloads constructor(
456456
UGraphics.DrawMode.QUADS,
457457
UGraphics.CommonVertexFormats.POSITION_COLOR,
458458
).apply {
459-
blendState = BlendState.NORMAL
459+
blendState = BlendState.ALPHA
460460
depthTest = URenderPipeline.DepthTest.Always
461461
}.build()
462462

@@ -465,7 +465,7 @@ class MenuButton @JvmOverloads constructor(
465465
UGraphics.DrawMode.QUADS,
466466
UGraphics.CommonVertexFormats.POSITION_TEXTURE_COLOR,
467467
).apply {
468-
blendState = BlendState.NORMAL
468+
blendState = BlendState.ALPHA
469469
depthTest = URenderPipeline.DepthTest.Always
470470
}.build()
471471

gui/essential/src/main/kotlin/gg/essential/gui/effects/AlphaEffect.kt

Lines changed: 74 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
*/
1212
package gg.essential.gui.effects
1313

14+
import gg.essential.elementa.components.UIBlock
1415
import gg.essential.elementa.effects.Effect
1516
import gg.essential.gui.elementa.state.v2.State
1617
import gg.essential.gui.elementa.state.v2.toV2
@@ -22,6 +23,7 @@ import gg.essential.universal.shader.BlendState
2223
import gg.essential.universal.vertex.UBufferBuilder
2324
import gg.essential.util.GuiEssentialPlatform.Companion.platform
2425
import gg.essential.util.image.GpuTexture
26+
import java.awt.Color
2527
import java.io.Closeable
2628
import java.lang.ref.PhantomReference
2729
import java.lang.ref.ReferenceQueue
@@ -68,6 +70,25 @@ class AlphaEffect(private val alphaState: State<Float>) : Effect() {
6870
resources.texture.copyFrom(listOf(GpuTexture.CopyOp(
6971
platform.mcFrameBufferColorTexture, x, y, 0, 0, width, height
7072
)))
73+
74+
// Clear the render target before we draw our content
75+
clear(matrixStack)
76+
}
77+
78+
private fun clear(matrixStack: UMatrixStack) {
79+
UBufferBuilder.create(UGraphics.DrawMode.QUADS, UGraphics.CommonVertexFormats.POSITION_COLOR).also { buffer ->
80+
UIBlock.drawBlock(
81+
buffer,
82+
matrixStack,
83+
// Note: The BlendState of CLEAR_PIPELINE will ignore this value, but MC's fragment shader will discard
84+
// pixels with alpha 0, so we must use a non-0 value here.
85+
Color(0, 0, 0, 255),
86+
boundComponent.getLeft().toDouble(),
87+
boundComponent.getTop().toDouble(),
88+
boundComponent.getRight().toDouble(),
89+
boundComponent.getBottom().toDouble(),
90+
)
91+
}.build()?.drawAndClose(CLEAR_PIPELINE)
7192
}
7293

7394
override fun afterDraw(matrixStack: UMatrixStack) {
@@ -86,18 +107,25 @@ class AlphaEffect(private val alphaState: State<Float>) : Effect() {
86107
return
87108
}
88109

89-
val red = 1f
90-
val green = 1f
91-
val blue = 1f
92-
val alpha = 1f - alphaState.get()
93-
94-
val worldRenderer = UBufferBuilder.create(UGraphics.DrawMode.QUADS, UGraphics.CommonVertexFormats.POSITION_TEXTURE_COLOR)
95-
worldRenderer.pos(matrixStack, x, y + height, 0.0).tex(0.0, 0.0).color(red, green, blue, alpha).endVertex()
96-
worldRenderer.pos(matrixStack, x + width, y + height, 0.0).tex(1.0, 0.0).color(red, green, blue, alpha).endVertex()
97-
worldRenderer.pos(matrixStack, x + width, y, 0.0).tex(1.0, 1.0).color(red, green, blue, alpha).endVertex()
98-
worldRenderer.pos(matrixStack, x, y, 0.0).tex(0.0, 1.0).color(red, green, blue, alpha).endVertex()
99-
worldRenderer.build()?.drawAndClose(PIPELINE) {
100-
texture("u_Texture", resources.texture.glId)
110+
// Make the thing we just rendered translucent (i.e. multiply it by the configured alpha factor)
111+
// Need a special case for 0 here because MC will discard fragments with alpha 0, but they are important for us
112+
val alpha = (alphaState.getUntracked() * 255).toInt()
113+
if (alpha != 0) {
114+
UBufferBuilder.create(UGraphics.DrawMode.QUADS, UGraphics.CommonVertexFormats.POSITION_COLOR).also { buffer ->
115+
UIBlock.drawBlock(buffer, matrixStack, Color(0, 0, 0, alpha), left, top, right, bottom)
116+
}.build()?.drawAndClose(MULTIPLY_PIPELINE)
117+
} else {
118+
clear(matrixStack)
119+
}
120+
121+
// Composite the background behind the content
122+
UBufferBuilder.create(UGraphics.DrawMode.QUADS, UGraphics.CommonVertexFormats.POSITION_TEXTURE).also { buffer ->
123+
buffer.pos(matrixStack, x, y + height, 0.0).tex(0.0, 0.0).endVertex()
124+
buffer.pos(matrixStack, x + width, y + height, 0.0).tex(1.0, 0.0).endVertex()
125+
buffer.pos(matrixStack, x + width, y, 0.0).tex(1.0, 1.0).endVertex()
126+
buffer.pos(matrixStack, x, y, 0.0).tex(0.0, 1.0).endVertex()
127+
}.build()?.drawAndClose(COMPOSITE_PIPELINE) {
128+
texture(0, resources.texture.glId)
101129
}
102130
}
103131

@@ -136,43 +164,39 @@ class AlphaEffect(private val alphaState: State<Float>) : Effect() {
136164
}
137165

138166
companion object {
139-
private val PIPELINE: URenderPipeline
140-
init {
141-
val vertexShaderSource = """
142-
#version 110
143-
144-
varying vec2 f_Position;
145-
varying vec2 f_TexCoord;
146-
147-
void main() {
148-
f_Position = gl_Vertex.xy;
149-
f_TexCoord = gl_MultiTexCoord0.st;
150-
151-
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
152-
gl_FrontColor = gl_Color;
153-
}
154-
""".trimIndent()
155-
val fragmentShaderSource = """
156-
#version 110
157-
158-
uniform sampler2D u_Texture;
159-
160-
varying vec2 f_Position;
161-
varying vec2 f_TexCoord;
162-
163-
void main() {
164-
gl_FragColor = gl_Color * vec4(texture2D(u_Texture, f_TexCoord).rgb, 1.0);
165-
}
166-
""".trimIndent()
167-
PIPELINE = URenderPipeline.builderWithLegacyShader(
168-
"elementa:alpha_effect",
169-
UGraphics.DrawMode.QUADS,
170-
UGraphics.CommonVertexFormats.POSITION_TEXTURE_COLOR,
171-
vertexShaderSource,
172-
fragmentShaderSource,
173-
).apply {
174-
blendState = BlendState.NORMAL
175-
}.build()
176-
}
167+
private val CLEAR_PIPELINE: URenderPipeline = URenderPipeline.builderWithDefaultShader(
168+
"elementa:alpha_effect/clear",
169+
UGraphics.DrawMode.QUADS,
170+
UGraphics.CommonVertexFormats.POSITION_COLOR,
171+
).apply {
172+
blendState = BlendState(BlendState.Equation.ADD, BlendState.Param.ZERO, BlendState.Param.ZERO)
173+
}.build()
174+
175+
private val MULTIPLY_PIPELINE: URenderPipeline = URenderPipeline.builderWithDefaultShader(
176+
"elementa:alpha_effect/multiply",
177+
UGraphics.DrawMode.QUADS,
178+
UGraphics.CommonVertexFormats.POSITION_COLOR,
179+
).apply {
180+
blendState = BlendState(
181+
BlendState.Equation.ADD,
182+
BlendState.Param.ZERO,
183+
BlendState.Param.SRC_ALPHA,
184+
)
185+
}.build()
186+
187+
private val COMPOSITE_PIPELINE: URenderPipeline = URenderPipeline.builderWithDefaultShader(
188+
"elementa:alpha_effect/composite",
189+
UGraphics.DrawMode.QUADS,
190+
UGraphics.CommonVertexFormats.POSITION_TEXTURE,
191+
).apply {
192+
// This is BlendState.PREMULTIPLIED_ALPHA but with the role of source and destination flipped because
193+
// it's the background which we have captured as a texture while the foreground was rendered into the
194+
// render target.
195+
blendState = BlendState(
196+
BlendState.Equation.ADD,
197+
BlendState.Param.ONE_MINUS_DST_ALPHA,
198+
BlendState.Param.ONE,
199+
)
200+
}.build()
177201
}
178202
}

gui/essential/src/main/kotlin/gg/essential/gui/screenshot/image/ScreenshotImage.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ open class ScreenshotImage(val texture: State<UIdentifier?>) : UIComponent() {
8282
UGraphics.DrawMode.QUADS,
8383
UGraphics.CommonVertexFormats.POSITION_TEXTURE_COLOR,
8484
).apply {
85-
blendState = BlendState.NORMAL
85+
blendState = BlendState.ALPHA
8686
}.build()
8787
}
8888
}

gui/essential/src/main/kotlin/gg/essential/gui/wardrobe/configuration/cosmetic/properties/VariantsPropertyConfiguration.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ class VariantsPropertyConfiguration(
398398
UGraphics.DrawMode.QUADS,
399399
UGraphics.CommonVertexFormats.POSITION_COLOR,
400400
).apply {
401-
blendState = BlendState.NORMAL
401+
blendState = BlendState.ALPHA
402402
}.build()
403403
}
404404
}

src/main/kotlin/gg/essential/gui/InternalEssentialGUI.kt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,15 @@ import gg.essential.api.EssentialAPI
1616
import gg.essential.api.gui.EssentialGUI
1717
import gg.essential.connectionmanager.common.packet.telemetry.ClientTelemetryPacket
1818
import gg.essential.elementa.ElementaVersion
19+
import gg.essential.elementa.components.UIBlock
1920
import gg.essential.gui.elementa.state.v2.State
2021
import gg.essential.gui.elementa.state.v2.mutableStateOf
22+
import gg.essential.universal.UGraphics
2123
import gg.essential.universal.UMatrixStack
24+
import gg.essential.universal.render.URenderPipeline
25+
import gg.essential.universal.shader.BlendState
26+
import gg.essential.universal.vertex.UBufferBuilder
27+
import java.awt.Color
2228

2329
abstract class InternalEssentialGUI(
2430
version: ElementaVersion,
@@ -42,6 +48,15 @@ abstract class InternalEssentialGUI(
4248
override fun onDrawScreen(matrixStack: UMatrixStack, mouseX: Int, mouseY: Int, partialTicks: Float) {
4349
super.onDrawScreen(matrixStack, mouseX, mouseY, partialTicks)
4450

51+
// Workaround for Elementa (or more generally `BlendState.NORMAL`) producing incorrect alpha output
52+
// prior to ElementaVersion.V10.
53+
// Upgrading past ElementaVersion.V8 is non-trivial, so we'll use this workaround until we've got all screens
54+
// upgraded. This assumes that the drawn content is supposed to be fully opaque, which is indeed the case for
55+
// all of our screens (except for `EmoteWheel`, which doesn't use this class).
56+
val buffer = UBufferBuilder.create(UGraphics.DrawMode.QUADS, UGraphics.CommonVertexFormats.POSITION_COLOR)
57+
UIBlock.drawBlock(buffer, matrixStack, Color.BLACK, 0.0, 0.0, window.getWidth().toDouble(), window.getHeight().toDouble())
58+
buffer.build()?.drawAndClose(TRANSPARENCY_WORKAROUND_PIPELINE)
59+
4560
if (openedAt == null) {
4661
openedAt = System.currentTimeMillis()
4762
}
@@ -65,4 +80,22 @@ abstract class InternalEssentialGUI(
6580
)
6681
)
6782
}
83+
84+
companion object {
85+
private val TRANSPARENCY_WORKAROUND_PIPELINE = URenderPipeline.builderWithDefaultShader(
86+
"essential:workaround_broken_transparency",
87+
UGraphics.DrawMode.QUADS,
88+
UGraphics.CommonVertexFormats.POSITION_COLOR,
89+
).apply {
90+
// Overwrites the framebuffer (dst) alpha, which is incorrect, with the drawn (src) alpha, which is always
91+
// 1, while keeping framebuffer color untouched.
92+
blendState = BlendState(
93+
equation = BlendState.Equation.ADD,
94+
srcRgb = BlendState.Param.ZERO,
95+
dstRgb = BlendState.Param.ONE,
96+
srcAlpha = BlendState.Param.ONE,
97+
dstAlpha = BlendState.Param.ZERO,
98+
)
99+
}.build()
100+
}
68101
}

0 commit comments

Comments
 (0)