mirror of
https://github.com/Wurst-Imperium/Wurst7.git
synced 2024-09-20 09:16:20 +02:00
Fix Navigator
This commit is contained in:
parent
1e3fbcccfd
commit
88720ef0a6
@ -7,13 +7,6 @@
|
||||
*/
|
||||
package net.wurstclient.navigator;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_BLEND;
|
||||
import static org.lwjgl.opengl.GL11.GL_CULL_FACE;
|
||||
import static org.lwjgl.opengl.GL11.GL_SCISSOR_TEST;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||
import static org.lwjgl.opengl.GL11.glDisable;
|
||||
import static org.lwjgl.opengl.GL11.glEnable;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.ArrayList;
|
||||
@ -29,10 +22,17 @@ import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.render.BufferBuilder;
|
||||
import net.minecraft.client.render.BufferRenderer;
|
||||
import net.minecraft.client.render.GameRenderer;
|
||||
import net.minecraft.client.render.Tessellator;
|
||||
import net.minecraft.client.render.VertexFormat;
|
||||
import net.minecraft.client.render.VertexFormats;
|
||||
import net.minecraft.client.sound.PositionedSoundInstance;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.util.math.Matrix4f;
|
||||
import net.wurstclient.Feature;
|
||||
import net.wurstclient.WurstClient;
|
||||
import net.wurstclient.clickgui.Component;
|
||||
@ -319,7 +319,7 @@ public final class NavigatorFeatureScreen extends NavigatorScreen
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
drawCenteredString(matrixStack, client.textRenderer, feature.getName(),
|
||||
middleX, 32, 0xffffff);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
|
||||
// background
|
||||
@ -329,20 +329,20 @@ public final class NavigatorFeatureScreen extends NavigatorScreen
|
||||
int bgy2 = height - 43;
|
||||
|
||||
setColorToBackground();
|
||||
drawQuads(bgx1, bgy1, bgx2,
|
||||
drawQuads(matrixStack, bgx1, bgy1, bgx2,
|
||||
Math.max(bgy1, Math.min(bgy2 - (buttons.isEmpty() ? 0 : 24),
|
||||
bgy1 + scroll + window.getY())));
|
||||
drawQuads(bgx1,
|
||||
drawQuads(matrixStack, bgx1,
|
||||
Math.max(bgy1,
|
||||
Math.min(bgy2 - (buttons.isEmpty() ? 0 : 24),
|
||||
bgy1 + scroll + window.getY() + window.getInnerHeight())),
|
||||
bgx2, bgy2);
|
||||
drawBoxShadow(bgx1, bgy1, bgx2, bgy2);
|
||||
drawBoxShadow(matrixStack, bgx1, bgy1, bgx2, bgy2);
|
||||
|
||||
// scissor box
|
||||
RenderUtils.scissorBox(bgx1, bgy1, bgx2,
|
||||
bgy2 - (buttons.isEmpty() ? 0 : 24));
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
GL11.glEnable(GL11.GL_SCISSOR_TEST);
|
||||
|
||||
// settings
|
||||
WurstClient.INSTANCE.getGui().setTooltip("");
|
||||
@ -354,67 +354,71 @@ public final class NavigatorFeatureScreen extends NavigatorScreen
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
|
||||
{
|
||||
// int x1 = 0;
|
||||
// int y1 = -13;
|
||||
// int x2 = x1 + window.getWidth();
|
||||
// int y2 = y1 + window.getHeight();
|
||||
// int y3 = y1 + 13;
|
||||
// int x3 = x1 + 2;
|
||||
// int x5 = x2 - 2;
|
||||
//
|
||||
// // window background
|
||||
// // left & right
|
||||
// setColorToBackground();
|
||||
// bufferBuilder.begin(VertexFormat.DrawMode.QUADS,
|
||||
// VertexFormats.POSITION);
|
||||
// GL11.glVertex2i(x1, y3);
|
||||
// GL11.glVertex2i(x1, y2);
|
||||
// GL11.glVertex2i(x3, y2);
|
||||
// GL11.glVertex2i(x3, y3);
|
||||
// GL11.glVertex2i(x5, y3);
|
||||
// GL11.glVertex2i(x5, y2);
|
||||
// GL11.glVertex2i(x2, y2);
|
||||
// GL11.glVertex2i(x2, y3);
|
||||
// bufferBuilder.end();
|
||||
// BufferRenderer.draw(bufferBuilder);
|
||||
//
|
||||
// setColorToBackground();
|
||||
// bufferBuilder.begin(VertexFormat.DrawMode.QUADS,
|
||||
// VertexFormats.POSITION);
|
||||
//
|
||||
// // window background
|
||||
// // between children
|
||||
// int xc1 = 2;
|
||||
// int xc2 = x5 - x1;
|
||||
// for(int i = 0; i < window.countChildren(); i++)
|
||||
// {
|
||||
// int yc1 = window.getChild(i).getY();
|
||||
// int yc2 = yc1 - 2;
|
||||
// GL11.glVertex2i(xc1, yc2);
|
||||
// GL11.glVertex2i(xc1, yc1);
|
||||
// GL11.glVertex2i(xc2, yc1);
|
||||
// GL11.glVertex2i(xc2, yc2);
|
||||
// }
|
||||
//
|
||||
// // window background
|
||||
// // bottom
|
||||
// int yc1;
|
||||
// if(window.countChildren() == 0)
|
||||
// yc1 = 0;
|
||||
// else
|
||||
// {
|
||||
// Component lastChild =
|
||||
// window.getChild(window.countChildren() - 1);
|
||||
// yc1 = lastChild.getY() + lastChild.getHeight();
|
||||
// }
|
||||
// int yc2 = yc1 + 2;
|
||||
// GL11.glVertex2i(xc1, yc2);
|
||||
// GL11.glVertex2i(xc1, yc1);
|
||||
// GL11.glVertex2i(xc2, yc1);
|
||||
// GL11.glVertex2i(xc2, yc2);
|
||||
//
|
||||
// bufferBuilder.end();
|
||||
// BufferRenderer.draw(bufferBuilder);
|
||||
int x1 = 0;
|
||||
int y1 = -13;
|
||||
int x2 = x1 + window.getWidth();
|
||||
int y2 = y1 + window.getHeight();
|
||||
int y3 = y1 + 13;
|
||||
int x3 = x1 + 2;
|
||||
int x5 = x2 - 2;
|
||||
|
||||
Matrix4f matrix = matrixStack.peek().getModel();
|
||||
BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
|
||||
RenderSystem.setShader(GameRenderer::method_34539);
|
||||
|
||||
// window background
|
||||
// left & right
|
||||
setColorToBackground();
|
||||
bufferBuilder.begin(VertexFormat.DrawMode.QUADS,
|
||||
VertexFormats.POSITION);
|
||||
bufferBuilder.vertex(matrix, x1, y3, 0).next();
|
||||
bufferBuilder.vertex(matrix, x1, y2, 0).next();
|
||||
bufferBuilder.vertex(matrix, x3, y2, 0).next();
|
||||
bufferBuilder.vertex(matrix, x3, y3, 0).next();
|
||||
bufferBuilder.vertex(matrix, x5, y3, 0).next();
|
||||
bufferBuilder.vertex(matrix, x5, y2, 0).next();
|
||||
bufferBuilder.vertex(matrix, x2, y2, 0).next();
|
||||
bufferBuilder.vertex(matrix, x2, y3, 0).next();
|
||||
bufferBuilder.end();
|
||||
BufferRenderer.draw(bufferBuilder);
|
||||
|
||||
setColorToBackground();
|
||||
bufferBuilder.begin(VertexFormat.DrawMode.QUADS,
|
||||
VertexFormats.POSITION);
|
||||
|
||||
// window background
|
||||
// between children
|
||||
int xc1 = 2;
|
||||
int xc2 = x5 - x1;
|
||||
for(int i = 0; i < window.countChildren(); i++)
|
||||
{
|
||||
int yc1 = window.getChild(i).getY();
|
||||
int yc2 = yc1 - 2;
|
||||
bufferBuilder.vertex(matrix, xc1, yc2, 0).next();
|
||||
bufferBuilder.vertex(matrix, xc1, yc1, 0).next();
|
||||
bufferBuilder.vertex(matrix, xc2, yc1, 0).next();
|
||||
bufferBuilder.vertex(matrix, xc2, yc2, 0).next();
|
||||
}
|
||||
|
||||
// window background
|
||||
// bottom
|
||||
int yc1;
|
||||
if(window.countChildren() == 0)
|
||||
yc1 = 0;
|
||||
else
|
||||
{
|
||||
Component lastChild =
|
||||
window.getChild(window.countChildren() - 1);
|
||||
yc1 = lastChild.getY() + lastChild.getHeight();
|
||||
}
|
||||
int yc2 = yc1 + 2;
|
||||
bufferBuilder.vertex(matrix, xc1, yc2, 0).next();
|
||||
bufferBuilder.vertex(matrix, xc1, yc1, 0).next();
|
||||
bufferBuilder.vertex(matrix, xc2, yc1, 0).next();
|
||||
bufferBuilder.vertex(matrix, xc2, yc2, 0).next();
|
||||
|
||||
bufferBuilder.end();
|
||||
BufferRenderer.draw(bufferBuilder);
|
||||
}
|
||||
|
||||
for(int i = 0; i < window.countChildren(); i++)
|
||||
@ -447,7 +451,7 @@ public final class NavigatorFeatureScreen extends NavigatorScreen
|
||||
RenderSystem.setShaderColor(rgb[0], rgb[1], rgb[2], alpha);
|
||||
|
||||
// button
|
||||
drawBox(x1, y1, x2, y2);
|
||||
drawBox(matrixStack, x1, y1, x2, y2);
|
||||
|
||||
// text
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
@ -455,7 +459,7 @@ public final class NavigatorFeatureScreen extends NavigatorScreen
|
||||
buttonData.buttonText, (x1 + x2) / 2,
|
||||
y1 + (buttonData.height - 10) / 2 + 1,
|
||||
buttonData.isLocked() ? 0xaaaaaa : buttonData.textColor);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
}
|
||||
|
||||
@ -471,7 +475,7 @@ public final class NavigatorFeatureScreen extends NavigatorScreen
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
|
||||
// scissor box
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
GL11.glDisable(GL11.GL_SCISSOR_TEST);
|
||||
|
||||
matrixStack.push();
|
||||
matrixStack.translate(bgx1, bgy1 + scroll - 13, 0);
|
||||
@ -505,8 +509,8 @@ public final class NavigatorFeatureScreen extends NavigatorScreen
|
||||
RenderSystem.setShaderColor(0.25F, 0.25F, 0.25F, 0.25F);
|
||||
|
||||
// button
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
drawBox(x1, y1, x2, y2);
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
drawBox(matrixStack, x1, y1, x2, y2);
|
||||
|
||||
// text
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
@ -517,9 +521,9 @@ public final class NavigatorFeatureScreen extends NavigatorScreen
|
||||
}
|
||||
|
||||
// GL resets
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
GL11.glEnable(GL11.GL_CULL_FACE);
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -18,8 +18,15 @@ import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.client.render.BufferBuilder;
|
||||
import net.minecraft.client.render.BufferRenderer;
|
||||
import net.minecraft.client.render.GameRenderer;
|
||||
import net.minecraft.client.render.Tessellator;
|
||||
import net.minecraft.client.render.VertexFormat;
|
||||
import net.minecraft.client.render.VertexFormats;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.util.math.Matrix4f;
|
||||
import net.wurstclient.Feature;
|
||||
import net.wurstclient.WurstClient;
|
||||
import net.wurstclient.clickgui.ClickGui;
|
||||
@ -224,9 +231,9 @@ public final class NavigatorMainScreen extends NavigatorScreen
|
||||
protected void onRender(MatrixStack matrixStack, int mouseX, int mouseY,
|
||||
float partialTicks)
|
||||
{
|
||||
// ClickGui gui = WurstClient.INSTANCE.getGui();
|
||||
// float[] bgColor = gui.getBgColor();
|
||||
// float[] acColor = gui.getAcColor();
|
||||
ClickGui gui = WurstClient.INSTANCE.getGui();
|
||||
float[] bgColor = gui.getBgColor();
|
||||
float[] acColor = gui.getAcColor();
|
||||
|
||||
boolean clickTimerRunning = clickTimer != -1;
|
||||
tooltip = null;
|
||||
@ -285,34 +292,39 @@ public final class NavigatorMainScreen extends NavigatorScreen
|
||||
int sh = client.currentScreen.height;
|
||||
|
||||
int xt1 = mouseX + tw + 11 <= sw ? mouseX + 8 : mouseX - tw - 8;
|
||||
// int xt2 = xt1 + tw + 3;
|
||||
int xt2 = xt1 + tw + 3;
|
||||
int yt1 = mouseY + th - 2 <= sh ? mouseY - 4 : mouseY - th - 4;
|
||||
// int yt2 = yt1 + th + 2;
|
||||
int yt2 = yt1 + th + 2;
|
||||
|
||||
Matrix4f matrix = matrixStack.peek().getModel();
|
||||
BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
|
||||
RenderSystem.setShader(GameRenderer::method_34539);
|
||||
|
||||
// background
|
||||
// GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
// RenderSystem.setShaderColor(bgColor[0], bgColor[1], bgColor[2],
|
||||
// 0.75F);
|
||||
// bufferBuilder.begin(VertexFormat.DrawMode.QUADS,
|
||||
// VertexFormats.POSITION);
|
||||
// GL11.glVertex2i(xt1, yt1);
|
||||
// GL11.glVertex2i(xt1, yt2);
|
||||
// GL11.glVertex2i(xt2, yt2);
|
||||
// GL11.glVertex2i(xt2, yt1);
|
||||
// bufferBuilder.end();
|
||||
// BufferRenderer.draw(bufferBuilder);
|
||||
//
|
||||
// // outline
|
||||
// RenderSystem.setShaderColor(acColor[0], acColor[1], acColor[2],
|
||||
// 0.5F);
|
||||
// bufferBuilder.begin(VertexFormat.DrawMode.LINE_LOOP,
|
||||
// VertexFormats.POSITION);
|
||||
// GL11.glVertex2i(xt1, yt1);
|
||||
// GL11.glVertex2i(xt1, yt2);
|
||||
// GL11.glVertex2i(xt2, yt2);
|
||||
// GL11.glVertex2i(xt2, yt1);
|
||||
// bufferBuilder.end();
|
||||
// BufferRenderer.draw(bufferBuilder);
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
RenderSystem.setShaderColor(bgColor[0], bgColor[1], bgColor[2],
|
||||
0.75F);
|
||||
bufferBuilder.begin(VertexFormat.DrawMode.QUADS,
|
||||
VertexFormats.POSITION);
|
||||
bufferBuilder.vertex(matrix, xt1, yt1, 0).next();
|
||||
bufferBuilder.vertex(matrix, xt1, yt2, 0).next();
|
||||
bufferBuilder.vertex(matrix, xt2, yt2, 0).next();
|
||||
bufferBuilder.vertex(matrix, xt2, yt1, 0).next();
|
||||
bufferBuilder.end();
|
||||
BufferRenderer.draw(bufferBuilder);
|
||||
|
||||
// outline
|
||||
RenderSystem.setShaderColor(acColor[0], acColor[1], acColor[2],
|
||||
0.5F);
|
||||
bufferBuilder.begin(VertexFormat.DrawMode.DEBUG_LINE_STRIP,
|
||||
VertexFormats.POSITION);
|
||||
bufferBuilder.vertex(matrix, xt1, yt1, 0).next();
|
||||
bufferBuilder.vertex(matrix, xt1, yt2, 0).next();
|
||||
bufferBuilder.vertex(matrix, xt2, yt2, 0).next();
|
||||
bufferBuilder.vertex(matrix, xt2, yt1, 0).next();
|
||||
bufferBuilder.vertex(matrix, xt1, yt1, 0).next();
|
||||
bufferBuilder.end();
|
||||
BufferRenderer.draw(bufferBuilder);
|
||||
|
||||
// text
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
@ -357,7 +369,7 @@ public final class NavigatorMainScreen extends NavigatorScreen
|
||||
area.height =
|
||||
(int)(area.height * antiFactor + (height - 103) * factor);
|
||||
|
||||
drawBackgroundBox(area.x, area.y, area.x + area.width,
|
||||
drawBackgroundBox(matrixStack, area.x, area.y, area.x + area.width,
|
||||
area.y + area.height);
|
||||
return;
|
||||
}
|
||||
@ -403,52 +415,60 @@ public final class NavigatorMainScreen extends NavigatorScreen
|
||||
tooltip = tt;
|
||||
|
||||
// box & shadow
|
||||
drawBox(area.x, area.y, area.x + area.width, area.y + area.height);
|
||||
drawBox(matrixStack, area.x, area.y, area.x + area.width,
|
||||
area.y + area.height);
|
||||
|
||||
Matrix4f matrix = matrixStack.peek().getModel();
|
||||
BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
|
||||
RenderSystem.setShader(GameRenderer::method_34539);
|
||||
|
||||
// separator
|
||||
int bx1 = area.x + area.width - area.height;
|
||||
// int by1 = area.y + 2;
|
||||
// int by2 = by1 + area.height - 4;
|
||||
// bufferBuilder.begin(VertexFormat.DrawMode.DEBUG_LINES,
|
||||
// VertexFormats.POSITION);
|
||||
// GL11.glVertex2i(bx1, by1);
|
||||
// GL11.glVertex2i(bx1, by2);
|
||||
// bufferBuilder.end();
|
||||
// BufferRenderer.draw(bufferBuilder);
|
||||
int by1 = area.y + 2;
|
||||
int by2 = by1 + area.height - 4;
|
||||
float[] acColor = WurstClient.INSTANCE.getGui().getAcColor();
|
||||
RenderSystem.setShaderColor(acColor[0], acColor[1], acColor[2], 0.5F);
|
||||
bufferBuilder.begin(VertexFormat.DrawMode.DEBUG_LINES,
|
||||
VertexFormats.POSITION);
|
||||
bufferBuilder.vertex(matrix, bx1, by1, 0).next();
|
||||
bufferBuilder.vertex(matrix, bx1, by2, 0).next();
|
||||
bufferBuilder.end();
|
||||
BufferRenderer.draw(bufferBuilder);
|
||||
|
||||
// hovering
|
||||
if(hovering)
|
||||
hoveringArrow = mouseX >= bx1;
|
||||
|
||||
// arrow positions
|
||||
// double oneThrird = area.height / 3D;
|
||||
// double twoThrirds = area.height * 2D / 3D;
|
||||
// double ax1 = bx1 + oneThrird - 2D;
|
||||
// double ax2 = bx1 + twoThrirds + 2D;
|
||||
// double ax3 = bx1 + area.height / 2D;
|
||||
// double ay1 = area.y + oneThrird;
|
||||
// double ay2 = area.y + twoThrirds;
|
||||
float oneThrird = area.height / 3F;
|
||||
float twoThrirds = area.height * 2F / 3F;
|
||||
float ax1 = bx1 + oneThrird - 2F;
|
||||
float ax2 = bx1 + twoThrirds + 2F;
|
||||
float ax3 = bx1 + area.height / 2F;
|
||||
float ay1 = area.y + oneThrird;
|
||||
float ay2 = area.y + twoThrirds;
|
||||
|
||||
// arrow
|
||||
RenderSystem.setShaderColor(0, hovering ? 1 : 0.85F, 0, 1);
|
||||
// bufferBuilder.begin(VertexFormat.DrawMode.TRIANGLES,
|
||||
// VertexFormats.POSITION);
|
||||
// GL11.glVertex2d(ax1, ay1);
|
||||
// GL11.glVertex2d(ax2, ay1);
|
||||
// GL11.glVertex2d(ax3, ay2);
|
||||
// bufferBuilder.end();
|
||||
// BufferRenderer.draw(bufferBuilder);
|
||||
bufferBuilder.begin(VertexFormat.DrawMode.TRIANGLES,
|
||||
VertexFormats.POSITION);
|
||||
bufferBuilder.vertex(matrix, ax1, ay1, 0).next();
|
||||
bufferBuilder.vertex(matrix, ax2, ay1, 0).next();
|
||||
bufferBuilder.vertex(matrix, ax3, ay2, 0).next();
|
||||
bufferBuilder.end();
|
||||
BufferRenderer.draw(bufferBuilder);
|
||||
|
||||
// arrow shadow
|
||||
GL11.glLineWidth(1);
|
||||
RenderSystem.setShaderColor(0.0625F, 0.0625F, 0.0625F, 0.5F);
|
||||
// bufferBuilder.begin(VertexFormat.DrawMode.LINE_LOOP,
|
||||
// VertexFormats.POSITION);
|
||||
// GL11.glVertex2d(ax1, ay1);
|
||||
// GL11.glVertex2d(ax2, ay1);
|
||||
// GL11.glVertex2d(ax3, ay2);
|
||||
// bufferBuilder.end();
|
||||
// BufferRenderer.draw(bufferBuilder);
|
||||
bufferBuilder.begin(VertexFormat.DrawMode.DEBUG_LINE_STRIP,
|
||||
VertexFormats.POSITION);
|
||||
bufferBuilder.vertex(matrix, ax1, ay1, 0).next();
|
||||
bufferBuilder.vertex(matrix, ax2, ay1, 0).next();
|
||||
bufferBuilder.vertex(matrix, ax3, ay2, 0).next();
|
||||
bufferBuilder.vertex(matrix, ax1, ay1, 0).next();
|
||||
bufferBuilder.end();
|
||||
BufferRenderer.draw(bufferBuilder);
|
||||
|
||||
// text
|
||||
if(!clickTimerRunning)
|
||||
|
@ -185,7 +185,7 @@ public class NavigatorNewKeybindScreen extends NavigatorScreen
|
||||
RenderSystem.setShaderColor(0.25F, 0.25F, 0.25F, 0.25F);
|
||||
|
||||
// button
|
||||
drawBox(x1, y1, x2, y2);
|
||||
drawBox(matrixStack, x1, y1, x2, y2);
|
||||
|
||||
// text
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
@ -233,7 +233,7 @@ public class NavigatorNewKeybindScreen extends NavigatorScreen
|
||||
|
||||
// button
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
drawBox(x1, y1, x2, y2);
|
||||
drawBox(matrixStack, x1, y1, x2, y2);
|
||||
|
||||
// text
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
|
@ -164,7 +164,7 @@ public class NavigatorRemoveKeybindScreen extends NavigatorScreen
|
||||
RenderSystem.setShaderColor(0.25F, 0.25F, 0.25F, 0.25F);
|
||||
|
||||
// button
|
||||
drawBox(x1, y1, x2, y2);
|
||||
drawBox(matrixStack, x1, y1, x2, y2);
|
||||
|
||||
// text
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
@ -213,7 +213,7 @@ public class NavigatorRemoveKeybindScreen extends NavigatorScreen
|
||||
|
||||
// button
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
drawBox(x1, y1, x2, y2);
|
||||
drawBox(matrixStack, x1, y1, x2, y2);
|
||||
|
||||
// text
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
|
@ -7,13 +7,22 @@
|
||||
*/
|
||||
package net.wurstclient.navigator;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.render.BufferBuilder;
|
||||
import net.minecraft.client.render.BufferRenderer;
|
||||
import net.minecraft.client.render.GameRenderer;
|
||||
import net.minecraft.client.render.Tessellator;
|
||||
import net.minecraft.client.render.VertexFormat;
|
||||
import net.minecraft.client.render.VertexFormats;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.util.math.Matrix4f;
|
||||
import net.wurstclient.WurstClient;
|
||||
|
||||
public abstract class NavigatorScreen extends Screen
|
||||
@ -138,11 +147,11 @@ public abstract class NavigatorScreen extends Screen
|
||||
float partialTicks)
|
||||
{
|
||||
// GL settings
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GL11.glDisable(GL11.GL_CULL_FACE);
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
// GL11.glShadeModel(GL11.GL_SMOOTH);
|
||||
|
||||
// background
|
||||
int bgx1 = middleX - 154;
|
||||
@ -150,7 +159,7 @@ public abstract class NavigatorScreen extends Screen
|
||||
int bgy1 = 60;
|
||||
int bgy2 = height - 43;
|
||||
if(hasBackground)
|
||||
drawBackgroundBox(bgx1, bgy1, bgx2, bgy2);
|
||||
drawBackgroundBox(matrixStack, bgx1, bgy1, bgx2, bgy2);
|
||||
|
||||
// scrollbar
|
||||
if(showScrollbar)
|
||||
@ -160,26 +169,26 @@ public abstract class NavigatorScreen extends Screen
|
||||
int x2 = x1 + 12;
|
||||
int y1 = bgy1;
|
||||
int y2 = bgy2;
|
||||
drawBackgroundBox(x1, y1, x2, y2);
|
||||
drawBackgroundBox(matrixStack, x1, y1, x2, y2);
|
||||
|
||||
// knob
|
||||
x1 += 2;
|
||||
x2 -= 2;
|
||||
y1 += scrollKnobPosition;
|
||||
y2 = y1 + 24;
|
||||
drawForegroundBox(x1, y1, x2, y2);
|
||||
drawForegroundBox(matrixStack, x1, y1, x2, y2);
|
||||
int i;
|
||||
for(x1++, x2--, y1 += 8, y2 -= 15, i = 0; i < 3; y1 += 4, y2 +=
|
||||
4, i++)
|
||||
drawDownShadow(x1, y1, x2, y2);
|
||||
drawDownShadow(matrixStack, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
onRender(matrixStack, mouseX, mouseY, partialTicks);
|
||||
|
||||
// GL resets
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
GL11.glEnable(GL11.GL_CULL_FACE);
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -227,193 +236,141 @@ public abstract class NavigatorScreen extends Screen
|
||||
scroll = maxScroll;
|
||||
}
|
||||
|
||||
protected final void drawQuads(int x1, int y1, int x2, int y2)
|
||||
protected final void drawQuads(MatrixStack matrixStack, int x1, int y1,
|
||||
int x2, int y2)
|
||||
{
|
||||
// bufferBuilder.begin(VertexFormat.DrawMode.QUADS,
|
||||
// VertexFormats.POSITION);
|
||||
// {
|
||||
// glVertex2i(x1, y1);
|
||||
// glVertex2i(x2, y1);
|
||||
// glVertex2i(x2, y2);
|
||||
// glVertex2i(x1, y2);
|
||||
// }
|
||||
// bufferBuilder.end();
|
||||
// BufferRenderer.draw(bufferBuilder);
|
||||
Matrix4f matrix = matrixStack.peek().getModel();
|
||||
BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
|
||||
RenderSystem.setShader(GameRenderer::method_34539);
|
||||
|
||||
bufferBuilder.begin(VertexFormat.DrawMode.QUADS,
|
||||
VertexFormats.POSITION);
|
||||
bufferBuilder.vertex(matrix, x1, y1, 0).next();
|
||||
bufferBuilder.vertex(matrix, x2, y1, 0).next();
|
||||
bufferBuilder.vertex(matrix, x2, y2, 0).next();
|
||||
bufferBuilder.vertex(matrix, x1, y2, 0).next();
|
||||
bufferBuilder.end();
|
||||
BufferRenderer.draw(bufferBuilder);
|
||||
}
|
||||
|
||||
protected final void drawBoxShadow(int x1, int y1, int x2, int y2)
|
||||
protected final void drawBoxShadow(MatrixStack matrixStack, int x1, int y1,
|
||||
int x2, int y2)
|
||||
{
|
||||
// // color
|
||||
// float[] acColor = WurstClient.INSTANCE.getGui().getAcColor();
|
||||
//
|
||||
// // outline positions
|
||||
// double xi1 = x1 - 0.1;
|
||||
// double xi2 = x2 + 0.1;
|
||||
// double yi1 = y1 - 0.1;
|
||||
// double yi2 = y2 + 0.1;
|
||||
//
|
||||
// // outline
|
||||
// glLineWidth(1F);
|
||||
// glColor4f(acColor[0], acColor[1], acColor[2], 0.5F);
|
||||
// bufferBuilder.begin(VertexFormat.DrawMode.LINE_LOOP,
|
||||
// VertexFormats.POSITION);
|
||||
// {
|
||||
// glVertex2d(xi1, yi1);
|
||||
// glVertex2d(xi2, yi1);
|
||||
// glVertex2d(xi2, yi2);
|
||||
// glVertex2d(xi1, yi2);
|
||||
// }
|
||||
// bufferBuilder.end();
|
||||
// BufferRenderer.draw(bufferBuilder);
|
||||
//
|
||||
// // shadow positions
|
||||
// xi1 -= 0.9;
|
||||
// xi2 += 0.9;
|
||||
// yi1 -= 0.9;
|
||||
// yi2 += 0.9;
|
||||
//
|
||||
// // top left
|
||||
// bufferBuilder.begin(VertexFormat.DrawMode.POLYGON,
|
||||
// VertexFormats.POSITION);
|
||||
// {
|
||||
// glColor4f(acColor[0], acColor[1], acColor[2], 0.75F);
|
||||
// glVertex2d(x1, y1);
|
||||
// glVertex2d(x2, y1);
|
||||
// glColor4f(0F, 0F, 0F, 0F);
|
||||
// glVertex2d(xi2, yi1);
|
||||
// glVertex2d(xi1, yi1);
|
||||
// glVertex2d(xi1, yi2);
|
||||
// glColor4f(acColor[0], acColor[1], acColor[2], 0.75F);
|
||||
// glVertex2d(x1, y2);
|
||||
// }
|
||||
// bufferBuilder.end();
|
||||
// BufferRenderer.draw(bufferBuilder);
|
||||
//
|
||||
// // bottom right
|
||||
// bufferBuilder.begin(VertexFormat.DrawMode.POLYGON,
|
||||
// VertexFormats.POSITION);
|
||||
// {
|
||||
// glVertex2d(x2, y2);
|
||||
// glVertex2d(x2, y1);
|
||||
// glColor4f(0F, 0F, 0F, 0F);
|
||||
// glVertex2d(xi2, yi1);
|
||||
// glVertex2d(xi2, yi2);
|
||||
// glVertex2d(xi1, yi2);
|
||||
// glColor4f(acColor[0], acColor[1], acColor[2], 0.75F);
|
||||
// glVertex2d(x1, y2);
|
||||
// }
|
||||
// bufferBuilder.end();
|
||||
// BufferRenderer.draw(bufferBuilder);
|
||||
// color
|
||||
float[] acColor = WurstClient.INSTANCE.getGui().getAcColor();
|
||||
|
||||
// outline positions
|
||||
float xi1 = x1 - 0.1F;
|
||||
float xi2 = x2 + 0.1F;
|
||||
float yi1 = y1 - 0.1F;
|
||||
float yi2 = y2 + 0.1F;
|
||||
|
||||
Matrix4f matrix = matrixStack.peek().getModel();
|
||||
BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
|
||||
RenderSystem.setShader(GameRenderer::method_34539);
|
||||
|
||||
// outline
|
||||
GL11.glLineWidth(1F);
|
||||
RenderSystem.setShaderColor(acColor[0], acColor[1], acColor[2], 0.5F);
|
||||
bufferBuilder.begin(VertexFormat.DrawMode.DEBUG_LINE_STRIP,
|
||||
VertexFormats.POSITION);
|
||||
bufferBuilder.vertex(matrix, xi1, yi1, 0).next();
|
||||
bufferBuilder.vertex(matrix, xi2, yi1, 0).next();
|
||||
bufferBuilder.vertex(matrix, xi2, yi2, 0).next();
|
||||
bufferBuilder.vertex(matrix, xi1, yi2, 0).next();
|
||||
bufferBuilder.vertex(matrix, xi1, yi1, 0).next();
|
||||
bufferBuilder.end();
|
||||
BufferRenderer.draw(bufferBuilder);
|
||||
|
||||
// shadow positions
|
||||
xi1 -= 0.9;
|
||||
xi2 += 0.9;
|
||||
yi1 -= 0.9;
|
||||
yi2 += 0.9;
|
||||
|
||||
RenderSystem.setShader(GameRenderer::method_34540);
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
|
||||
bufferBuilder.begin(VertexFormat.DrawMode.QUADS,
|
||||
VertexFormats.POSITION_COLOR);
|
||||
|
||||
// top
|
||||
bufferBuilder.vertex(matrix, x1, y1, 0)
|
||||
.color(acColor[0], acColor[1], acColor[2], 0.75F).next();
|
||||
bufferBuilder.vertex(matrix, x2, y1, 0)
|
||||
.color(acColor[0], acColor[1], acColor[2], 0.75F).next();
|
||||
bufferBuilder.vertex(matrix, xi2, yi1, 0).color(0, 0, 0, 0).next();
|
||||
bufferBuilder.vertex(matrix, xi1, yi1, 0).color(0, 0, 0, 0).next();
|
||||
|
||||
// left
|
||||
bufferBuilder.vertex(matrix, xi1, yi1, 0).color(0, 0, 0, 0).next();
|
||||
bufferBuilder.vertex(matrix, xi1, yi2, 0).color(0, 0, 0, 0).next();
|
||||
bufferBuilder.vertex(matrix, x1, y2, 0)
|
||||
.color(acColor[0], acColor[1], acColor[2], 0.75F).next();
|
||||
bufferBuilder.vertex(matrix, x1, y1, 0)
|
||||
.color(acColor[0], acColor[1], acColor[2], 0.75F).next();
|
||||
|
||||
// right
|
||||
bufferBuilder.vertex(matrix, x2, y2, 0)
|
||||
.color(acColor[0], acColor[1], acColor[2], 0.75F).next();
|
||||
bufferBuilder.vertex(matrix, x2, y1, 0)
|
||||
.color(acColor[0], acColor[1], acColor[2], 0.75F).next();
|
||||
bufferBuilder.vertex(matrix, xi2, yi1, 0).color(0, 0, 0, 0).next();
|
||||
bufferBuilder.vertex(matrix, xi2, yi2, 0).color(0, 0, 0, 0).next();
|
||||
|
||||
// bottom
|
||||
bufferBuilder.vertex(matrix, xi2, yi2, 0).color(0, 0, 0, 0).next();
|
||||
bufferBuilder.vertex(matrix, xi1, yi2, 0).color(0, 0, 0, 0).next();
|
||||
bufferBuilder.vertex(matrix, x1, y2, 0)
|
||||
.color(acColor[0], acColor[1], acColor[2], 0.75F).next();
|
||||
bufferBuilder.vertex(matrix, x2, y2, 0)
|
||||
.color(acColor[0], acColor[1], acColor[2], 0.75F).next();
|
||||
|
||||
bufferBuilder.end();
|
||||
BufferRenderer.draw(bufferBuilder);
|
||||
}
|
||||
|
||||
protected final void drawInvertedBoxShadow(int x1, int y1, int x2, int y2)
|
||||
protected final void drawDownShadow(MatrixStack matrixStack, int x1, int y1,
|
||||
int x2, int y2)
|
||||
{
|
||||
// // color
|
||||
// float[] acColor = WurstClient.INSTANCE.getGui().getAcColor();
|
||||
//
|
||||
// // outline positions
|
||||
// double xi1 = x1 + 0.1;
|
||||
// double xi2 = x2 - 0.1;
|
||||
// double yi1 = y1 + 0.1;
|
||||
// double yi2 = y2 - 0.1;
|
||||
//
|
||||
// // outline
|
||||
// glLineWidth(1F);
|
||||
// glColor4f(acColor[0], acColor[1], acColor[2], 0.5F);
|
||||
// bufferBuilder.begin(VertexFormat.DrawMode.LINE_LOOP,
|
||||
// VertexFormats.POSITION);
|
||||
// {
|
||||
// glVertex2d(xi1, yi1);
|
||||
// glVertex2d(xi2, yi1);
|
||||
// glVertex2d(xi2, yi2);
|
||||
// glVertex2d(xi1, yi2);
|
||||
// }
|
||||
// bufferBuilder.end();
|
||||
// BufferRenderer.draw(bufferBuilder);
|
||||
//
|
||||
// // shadow positions
|
||||
// xi1 += 0.9;
|
||||
// xi2 -= 0.9;
|
||||
// yi1 += 0.9;
|
||||
// yi2 -= 0.9;
|
||||
//
|
||||
// // top left
|
||||
// bufferBuilder.begin(VertexFormat.DrawMode.POLYGON,
|
||||
// VertexFormats.POSITION);
|
||||
// {
|
||||
// glColor4f(acColor[0], acColor[1], acColor[2], 0.75F);
|
||||
// glVertex2d(x1, y1);
|
||||
// glVertex2d(x2, y1);
|
||||
// glColor4f(0F, 0F, 0F, 0F);
|
||||
// glVertex2d(xi2, yi1);
|
||||
// glVertex2d(xi1, yi1);
|
||||
// glVertex2d(xi1, yi2);
|
||||
// glColor4f(acColor[0], acColor[1], acColor[2], 0.75F);
|
||||
// glVertex2d(x1, y2);
|
||||
// }
|
||||
// bufferBuilder.end();
|
||||
// BufferRenderer.draw(bufferBuilder);
|
||||
//
|
||||
// // bottom right
|
||||
// bufferBuilder.begin(VertexFormat.DrawMode.POLYGON,
|
||||
// VertexFormats.POSITION);
|
||||
// {
|
||||
// glVertex2d(x2, y2);
|
||||
// glVertex2d(x2, y1);
|
||||
// glColor4f(0F, 0F, 0F, 0F);
|
||||
// glVertex2d(xi2, yi1);
|
||||
// glVertex2d(xi2, yi2);
|
||||
// glVertex2d(xi1, yi2);
|
||||
// glColor4f(acColor[0], acColor[1], acColor[2], 0.75F);
|
||||
// glVertex2d(x1, y2);
|
||||
// }
|
||||
// bufferBuilder.end();
|
||||
// BufferRenderer.draw(bufferBuilder);
|
||||
// color
|
||||
float[] acColor = WurstClient.INSTANCE.getGui().getAcColor();
|
||||
|
||||
Matrix4f matrix = matrixStack.peek().getModel();
|
||||
BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
|
||||
RenderSystem.setShader(GameRenderer::method_34539);
|
||||
|
||||
// outline
|
||||
float yi1 = y1 + 0.1F;
|
||||
GL11.glLineWidth(1F);
|
||||
RenderSystem.setShaderColor(acColor[0], acColor[1], acColor[2], 0.5F);
|
||||
bufferBuilder.begin(VertexFormat.DrawMode.DEBUG_LINES,
|
||||
VertexFormats.POSITION);
|
||||
bufferBuilder.vertex(matrix, x1, yi1, 0).next();
|
||||
bufferBuilder.vertex(matrix, x2, yi1, 0).next();
|
||||
bufferBuilder.end();
|
||||
BufferRenderer.draw(bufferBuilder);
|
||||
|
||||
// shadow
|
||||
RenderSystem.setShader(GameRenderer::method_34540);
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||
bufferBuilder.begin(VertexFormat.DrawMode.QUADS,
|
||||
VertexFormats.POSITION_COLOR);
|
||||
bufferBuilder.vertex(matrix, x1, y1, 0)
|
||||
.color(acColor[0], acColor[1], acColor[2], 0.75F).next();
|
||||
bufferBuilder.vertex(matrix, x2, y1, 0)
|
||||
.color(acColor[0], acColor[1], acColor[2], 0.75F).next();
|
||||
bufferBuilder.vertex(matrix, x2, y2, 0).color(0, 0, 0, 0).next();
|
||||
bufferBuilder.vertex(matrix, x1, y2, 0).color(0, 0, 0, 0).next();
|
||||
bufferBuilder.end();
|
||||
BufferRenderer.draw(bufferBuilder);
|
||||
}
|
||||
|
||||
protected final void drawDownShadow(int x1, int y1, int x2, int y2)
|
||||
protected final void drawBox(MatrixStack matrixStack, int x1, int y1,
|
||||
int x2, int y2)
|
||||
{
|
||||
// // color
|
||||
// float[] acColor = WurstClient.INSTANCE.getGui().getAcColor();
|
||||
//
|
||||
// // outline
|
||||
// double yi1 = y1 + 0.1;
|
||||
// glLineWidth(1F);
|
||||
// glColor4f(acColor[0], acColor[1], acColor[2], 0.5F);
|
||||
// bufferBuilder.begin(VertexFormat.DrawMode.DEBUG_LINES,
|
||||
// VertexFormats.POSITION);
|
||||
// {
|
||||
// glVertex2d(x1, yi1);
|
||||
// glVertex2d(x2, yi1);
|
||||
// }
|
||||
// bufferBuilder.end();
|
||||
// BufferRenderer.draw(bufferBuilder);
|
||||
//
|
||||
// // shadow
|
||||
// bufferBuilder.begin(VertexFormat.DrawMode.POLYGON,
|
||||
// VertexFormats.POSITION);
|
||||
// {
|
||||
// glColor4f(acColor[0], acColor[1], acColor[2], 0.75F);
|
||||
// glVertex2i(x1, y1);
|
||||
// glVertex2i(x2, y1);
|
||||
// glColor4f(0F, 0F, 0F, 0F);
|
||||
// glVertex2i(x2, y2);
|
||||
// glVertex2i(x1, y2);
|
||||
// }
|
||||
// bufferBuilder.end();
|
||||
// BufferRenderer.draw(bufferBuilder);
|
||||
}
|
||||
|
||||
protected final void drawBox(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
drawQuads(x1, y1, x2, y2);
|
||||
drawBoxShadow(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
protected final void drawEngravedBox(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
drawQuads(x1, y1, x2, y2);
|
||||
drawInvertedBoxShadow(x1, y1, x2, y2);
|
||||
drawQuads(matrixStack, x1, y1, x2, y2);
|
||||
drawBoxShadow(matrixStack, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
protected final void setColorToBackground()
|
||||
@ -421,7 +378,8 @@ public abstract class NavigatorScreen extends Screen
|
||||
WurstClient.INSTANCE.getGui().updateColors();
|
||||
float[] bgColor = WurstClient.INSTANCE.getGui().getBgColor();
|
||||
float opacity = WurstClient.INSTANCE.getGui().getOpacity();
|
||||
glColor4f(bgColor[0], bgColor[1], bgColor[2], opacity);
|
||||
RenderSystem.setShaderColor(bgColor[0], bgColor[1], bgColor[2],
|
||||
opacity);
|
||||
}
|
||||
|
||||
protected final void setColorToForeground()
|
||||
@ -429,18 +387,21 @@ public abstract class NavigatorScreen extends Screen
|
||||
WurstClient.INSTANCE.getGui().updateColors();
|
||||
float[] bgColor = WurstClient.INSTANCE.getGui().getBgColor();
|
||||
float opacity = WurstClient.INSTANCE.getGui().getOpacity();
|
||||
glColor4f(bgColor[0], bgColor[1], bgColor[2], opacity);
|
||||
RenderSystem.setShaderColor(bgColor[0], bgColor[1], bgColor[2],
|
||||
opacity);
|
||||
}
|
||||
|
||||
protected final void drawBackgroundBox(int x1, int y1, int x2, int y2)
|
||||
protected final void drawBackgroundBox(MatrixStack matrixStack, int x1,
|
||||
int y1, int x2, int y2)
|
||||
{
|
||||
setColorToBackground();
|
||||
drawBox(x1, y1, x2, y2);
|
||||
drawBox(matrixStack, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
protected final void drawForegroundBox(int x1, int y1, int x2, int y2)
|
||||
protected final void drawForegroundBox(MatrixStack matrixStack, int x1,
|
||||
int y1, int x2, int y2)
|
||||
{
|
||||
setColorToForeground();
|
||||
drawBox(x1, y1, x2, y2);
|
||||
drawBox(matrixStack, x1, y1, x2, y2);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user