Update #28 - Added capes, voice chat, FNAW skins, and fixes

This commit is contained in:
lax1dude
2024-04-20 16:20:06 -07:00
parent 42c57894f9
commit ba88b52022
171 changed files with 7476 additions and 868 deletions

View File

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.voice;
/**
* Copyright (c) 2024 ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public enum EnumVoiceChannelPeerState {
FAILED, SUCCESS, LOADING;
}

View File

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.voice;
/**
* Copyright (c) 2024 ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public enum EnumVoiceChannelReadyState {
NONE, ABORTED, DEVICE_INITIALIZED;
}

View File

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.voice;
/**
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public enum EnumVoiceChannelStatus {
DISCONNECTED, CONNECTING, CONNECTED, UNAVAILABLE;
}

View File

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.voice;
/**
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public enum EnumVoiceChannelType {
NONE, GLOBAL, PROXIMITY;
}

View File

@ -0,0 +1,84 @@
package net.lax1dude.eaglercraft.v1_8.voice;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
/**
* Copyright (c) 2022 ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class ExpiringSet<T> extends HashSet<T> {
private final long expiration;
private final ExpiringEvent<T> event;
private final Map<T, Long> timestamps = new HashMap<>();
public ExpiringSet(long expiration) {
this.expiration = expiration;
this.event = null;
}
public ExpiringSet(long expiration, ExpiringEvent<T> event) {
this.expiration = expiration;
this.event = event;
}
public interface ExpiringEvent<T> {
void onExpiration(T item);
}
public void checkForExpirations() {
Iterator<T> iterator = this.timestamps.keySet().iterator();
long now = System.currentTimeMillis();
while (iterator.hasNext()) {
T element = iterator.next();
if (super.contains(element)) {
if (this.timestamps.get(element) + this.expiration < now) {
if (this.event != null) this.event.onExpiration(element);
iterator.remove();
super.remove(element);
}
} else {
iterator.remove();
super.remove(element);
}
}
}
public boolean add(T o) {
checkForExpirations();
boolean success = super.add(o);
if (success) timestamps.put(o, System.currentTimeMillis());
return success;
}
public boolean remove(Object o) {
checkForExpirations();
boolean success = super.remove(o);
if (success) timestamps.remove(o);
return success;
}
public void clear() {
this.timestamps.clear();
super.clear();
}
public boolean contains(Object o) {
checkForExpirations();
return super.contains(o);
}
}

View File

@ -0,0 +1,772 @@
package net.lax1dude.eaglercraft.v1_8.voice;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import java.util.List;
import java.util.Set;
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
import net.lax1dude.eaglercraft.v1_8.Keyboard;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.lax1dude.eaglercraft.v1_8.sp.gui.GuiSlider2;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
/**
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class GuiVoiceMenu extends Gui {
public class AbortedException extends RuntimeException {
}
private static final ResourceLocation voiceGuiIcons = new ResourceLocation("eagler:gui/eagler_gui.png");
protected final GuiScreen parent;
protected Minecraft mc;
protected FontRenderer fontRendererObj;
protected int width;
protected int height;
protected int voiceButtonOFFposX;
protected int voiceButtonOFFposY;
protected int voiceButtonOFFposW;
protected int voiceButtonOFFposH;
protected int voiceButtonRADIUSposX;
protected int voiceButtonRADIUSposY;
protected int voiceButtonRADIUSposW;
protected int voiceButtonRADIUSposH;
protected int voiceButtonGLOBALposX;
protected int voiceButtonGLOBALposY;
protected int voiceButtonGLOBALposW;
protected int voiceButtonGLOBALposH;
protected int voiceScreenButtonOFFposX;
protected int voiceScreenButtonOFFposY;
protected int voiceScreenButtonOFFposW;
protected int voiceScreenButtonOFFposH;
protected int voiceScreenButtonRADIUSposX;
protected int voiceScreenButtonRADIUSposY;
protected int voiceScreenButtonRADIUSposW;
protected int voiceScreenButtonRADIUSposH;
protected int voiceScreenButtonGLOBALposX;
protected int voiceScreenButtonGLOBALposY;
protected int voiceScreenButtonGLOBALposW;
protected int voiceScreenButtonGLOBALposH;
protected int voiceScreenButtonChangeRadiusposX;
protected int voiceScreenButtonChangeRadiusposY;
protected int voiceScreenButtonChangeRadiusposW;
protected int voiceScreenButtonChangeRadiusposH;
protected int voiceScreenVolumeIndicatorX;
protected int voiceScreenVolumeIndicatorY;
protected int voiceScreenVolumeIndicatorW;
protected int voiceScreenVolumeIndicatorH;
protected boolean showSliderBlocks = false;
protected boolean showSliderVolume = false;
protected boolean showPTTKeyConfig = false;
protected int showNewPTTKey = 0;
protected GuiSlider2 sliderBlocks = null;
protected GuiSlider2 sliderListenVolume = null;
protected GuiSlider2 sliderSpeakVolume = null;
protected GuiButton applyRadiusButton = null;
protected GuiButton applyVolumeButton = null;
protected GuiButton noticeContinueButton = null;
protected GuiButton noticeCancelButton = null;
protected static boolean showingCompatWarning = false;
protected static boolean showCompatWarning = true;
protected static boolean showingTrackingWarning = false;
protected static boolean showTrackingWarning = true;
protected static EnumVoiceChannelType continueChannel = null;
public GuiVoiceMenu(GuiScreen parent) {
this.parent = parent;
}
public void setResolution(Minecraft mc, int w, int h) {
this.mc = mc;
this.fontRendererObj = mc.fontRendererObj;
this.width = w;
this.height = h;
initGui();
}
public void initGui() {
this.sliderBlocks = new GuiSlider2(-1, (width - 150) / 2, height / 3 + 20, 150, 20, (VoiceClientController.getVoiceProximity() - 5) / 17.0f, 1.0f) {
public boolean mousePressed(Minecraft par1Minecraft, int par2, int par3) {
if(super.mousePressed(par1Minecraft, par2, par3)) {
this.displayString = "" + (int)((sliderValue * 17.0f) + 5.0f) + " Blocks";
return true;
}else {
return false;
}
}
public void mouseDragged(Minecraft par1Minecraft, int par2, int par3) {
super.mouseDragged(par1Minecraft, par2, par3);
this.displayString = "" + (int)((sliderValue * 17.0f) + 5.0f) + " Blocks";
}
};
sliderBlocks.displayString = "" + VoiceClientController.getVoiceProximity() + " Blocks";
this.sliderListenVolume = new GuiSlider2(-1, (width - 150) / 2, height / 3 + 10, 150, 20, VoiceClientController.getVoiceListenVolume(), 1.0f);
this.sliderSpeakVolume = new GuiSlider2(-1, (width - 150) / 2, height / 3 + 56, 150, 20, VoiceClientController.getVoiceSpeakVolume(), 1.0f);
applyRadiusButton = new GuiButton(2, (width - 150) / 2, height / 3 + 49, 150, 20, I18n.format("voice.apply"));
applyVolumeButton = new GuiButton(3, (width - 150) / 2, height / 3 + 90, 150, 20, I18n.format("voice.apply"));
noticeContinueButton = new GuiButton(5, (width - 150) / 2, height / 3 + 60, 150, 20, I18n.format("voice.unsupportedWarning10"));
noticeCancelButton = new GuiButton(6, (width - 150) / 2, height / 3 + 90, 150, 20, I18n.format("voice.unsupportedWarning11"));
applyRadiusButton.visible = applyVolumeButton.visible = noticeContinueButton.visible = noticeCancelButton.visible = false;
}
private void drawButtons(int mx, int my, float partialTicks) {
applyRadiusButton.drawButton(mc, mx, my);
applyVolumeButton.drawButton(mc, mx, my);
noticeContinueButton.drawButton(mc, mx, my);
noticeCancelButton.drawButton(mc, mx, my);
}
public void drawScreen(int mx, int my, float partialTicks) {
String txt = I18n.format("voice.title");
drawString(fontRendererObj, txt, width - 5 - fontRendererObj.getStringWidth(txt), 5, 0xFFCC22);
applyRadiusButton.visible = showSliderBlocks;
applyVolumeButton.visible = showSliderVolume;
if(showSliderBlocks || showSliderVolume || showPTTKeyConfig) {
drawRect(0, 0, this.width, this.height, 0xB0101010);
if(showSliderBlocks) {
drawRect(width / 2 - 86, height / 4 - 1, this.width / 2 + 86, height / 3 + 64 + height / 16, 0xFFDDDDDD);
drawRect(width / 2 - 85, height / 4 + 0, this.width / 2 + 85, height / 3 + 63 + height / 16, 0xFF333333);
drawCenteredString(this.fontRendererObj, I18n.format("voice.radiusTitle"), this.width / 2, height / 4 + 9, 16777215);
drawString(this.fontRendererObj, I18n.format("voice.radiusLabel"), (this.width - 150) / 2 + 3, height / 3 + 6, 0xCCCCCC);
sliderBlocks.drawButton(mc, mx, my);
}else if(showSliderVolume) {
drawRect(width / 2 - 86, height / 4 - 11, this.width / 2 + 86, height / 3 + 104 + height / 16, 0xFFDDDDDD);
drawRect(width / 2 - 85, height / 4 - 10, this.width / 2 + 85, height / 3 + 103 + height / 16, 0xFF333333);
drawCenteredString(this.fontRendererObj, I18n.format("voice.volumeTitle"), this.width / 2, height / 4 - 1, 16777215);
drawString(this.fontRendererObj, I18n.format("voice.volumeListen"), (this.width - 150) / 2 + 3, height / 3 - 4, 0xCCCCCC);
sliderListenVolume.drawButton(mc, mx, my);
drawString(this.fontRendererObj, I18n.format("voice.volumeSpeak"), (this.width - 150) / 2 + 3, height / 3 + 42, 0xCCCCCC);
sliderSpeakVolume.drawButton(mc, mx, my);
}else if(showPTTKeyConfig) {
drawRect(width / 2 - 86, height / 3 - 10, this.width / 2 + 86, height / 3 + 35, 0xFFDDDDDD);
drawRect(width / 2 - 85, height / 3 - 9, this.width / 2 + 85, height / 3 + 34, 0xFF333333);
if(showNewPTTKey > 0) {
GlStateManager.pushMatrix();
GlStateManager.translate(this.width / 2, height / 3 + 5, 0.0f);
GlStateManager.scale(2.0f, 2.0f, 2.0f);
drawCenteredString(this.fontRendererObj, Keyboard.getKeyName(mc.gameSettings.voicePTTKey), 0, 0, 0xFFCC11);
GlStateManager.popMatrix();
}else {
drawCenteredString(this.fontRendererObj, I18n.format("voice.pttChangeDesc"), this.width / 2, height / 3 + 8, 16777215);
}
}
drawButtons(mx, my, partialTicks);
throw new AbortedException();
}
GlStateManager.pushMatrix();
GlStateManager.translate(width - 6, 15, 0.0f);
GlStateManager.scale(0.75f, 0.75f, 0.75f);
if(!VoiceClientController.isClientSupported()) {
txt = I18n.format("voice.titleVoiceUnavailable");
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 6, 0xFF7777);
txt = I18n.format("voice.titleVoiceBrowserError");
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 19, 0xAA4444);
GlStateManager.popMatrix();
return;
}
if(!VoiceClientController.isServerSupported()) {
txt = I18n.format("voice.titleNoVoice");
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 5, 0xFF7777);
GlStateManager.popMatrix();
return;
}
int xo = 0;
// this feature is optional
//if(VoiceClientController.voiceRelayed()) {
// txt = I18n.format("voice.warning1");
// drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 8, 0xBB9999);
// txt = I18n.format("voice.warning2");
// drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 18, 0xBB9999);
// txt = I18n.format("voice.warning3");
// drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 28, 0xBB9999);
// xo = 43;
// GlStateManager.translate(0.0f, xo, 0.0f);
//}
EnumVoiceChannelStatus status = VoiceClientController.getVoiceStatus();
EnumVoiceChannelType channel = VoiceClientController.getVoiceChannel();
boolean flag = false;
if(channel == EnumVoiceChannelType.NONE) {
flag = true;
}else {
if(status == EnumVoiceChannelStatus.CONNECTED) {
if(channel == EnumVoiceChannelType.PROXIMITY) {
txt = I18n.format("voice.connectedRadius").replace("$radius$", "" + VoiceClientController.getVoiceProximity()).replace("$f$", "");
int w = fontRendererObj.getStringWidth(txt);
int xx = width - 5 - (w * 3 / 4);
int yy = 15 + (xo * 3 / 4);
voiceScreenButtonChangeRadiusposX = xx;
voiceScreenButtonChangeRadiusposY = yy;
voiceScreenButtonChangeRadiusposW = width - 3 - xx;
voiceScreenButtonChangeRadiusposH = 12;
if(mx >= xx && my >= yy && mx < xx + voiceScreenButtonChangeRadiusposW && my < yy + 12) {
txt = I18n.format("voice.connectedRadius").replace("$radius$", "" + VoiceClientController.getVoiceProximity())
.replace("$f$", "" + EnumChatFormatting.UNDERLINE) + EnumChatFormatting.RESET;
}
}else {
txt = I18n.format("voice.connectedGlobal");
}
voiceScreenVolumeIndicatorX = width - 15 - (104 * 3 / 4);
voiceScreenVolumeIndicatorY = 15 + (xo * 3 / 4) + 30;
voiceScreenVolumeIndicatorW = width - voiceScreenVolumeIndicatorX - 4;
voiceScreenVolumeIndicatorH = 23;
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 5, 0x66DD66);
drawRect(-90, 42, 2, 52, 0xFFAAAAAA);
drawRect(-89, 43, 1, 51, 0xFF222222);
float vol = VoiceClientController.getVoiceListenVolume();
drawRect(-89, 43, -89 + (int)(vol * 90), 51, 0xFF993322);
for(float f = 0.07f; f < vol; f += 0.08f) {
int ww = (int)(f * 90);
drawRect(-89 + ww, 43, -89 + ww + 1, 51, 0xFF999999);
}
drawRect(-90, 57, 2, 67, 0xFFAAAAAA);
drawRect(-89, 58, 1, 66, 0xFF222222);
vol = VoiceClientController.getVoiceSpeakVolume();
drawRect(-89, 58, -89 + (int)(vol * 90), 66, 0xFF993322);
for(float f = 0.07f; f < vol; f += 0.08f) {
int ww = (int)(f * 90);
drawRect(-89 + ww, 58, -89 + ww + 1, 66, 0xFF999999);
}
mc.getTextureManager().bindTexture(voiceGuiIcons);
GlStateManager.color(0.7f, 0.7f, 0.7f, 1.0f);
GlStateManager.pushMatrix();
GlStateManager.translate(-104.0f, 41.5f, 0.0f);
GlStateManager.scale(0.7f, 0.7f, 0.7f);
drawTexturedModalRect(0, 0, 64, 144, 16, 16);
GlStateManager.popMatrix();
GlStateManager.pushMatrix();
GlStateManager.translate(-104.0f, 56.5f, 0.0f);
GlStateManager.scale(0.7f, 0.7f, 0.7f);
if((mc.currentScreen == null || !mc.currentScreen.blockPTTKey()) && Keyboard.isKeyDown(mc.gameSettings.voicePTTKey)) {
GlStateManager.color(0.9f, 0.4f, 0.4f, 1.0f);
drawTexturedModalRect(0, 0, 64, 64, 16, 16);
}else {
drawTexturedModalRect(0, 0, 64, 32, 16, 16);
}
GlStateManager.popMatrix();
txt = I18n.format("voice.ptt", Keyboard.getKeyName(mc.gameSettings.voicePTTKey));
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt) - 10, 76, 0x66DD66);
mc.getTextureManager().bindTexture(voiceGuiIcons);
GlStateManager.color(0.4f, 0.9f, 0.4f, 1.0f);
GlStateManager.pushMatrix();
GlStateManager.translate(-7.0f, 74.5f, 0.0f);
GlStateManager.scale(0.35f, 0.35f, 0.35f);
drawTexturedModalRect(0, 0, 32, 224, 32, 32);
GlStateManager.popMatrix();
txt = I18n.format("voice.playersListening");
GlStateManager.pushMatrix();
GlStateManager.translate(0.0f, 98.0f, 0.0f);
GlStateManager.scale(1.2f, 1.2f, 1.2f);
drawString(fontRendererObj, txt, -fontRendererObj.getStringWidth(txt), 0, 0xFF7777);
GlStateManager.popMatrix();
List<EaglercraftUUID> playersToRender = VoiceClientController.getVoiceRecent();
if(playersToRender.size() > 0) {
EaglercraftUUID uuid;
Set<EaglercraftUUID> playersSpeaking = VoiceClientController.getVoiceSpeaking();
Set<EaglercraftUUID> playersMuted = VoiceClientController.getVoiceMuted();
for(int i = 0, l = playersToRender.size(); i < l; ++i) {
uuid = playersToRender.get(i);
txt = VoiceClientController.getVoiceUsername(uuid);
boolean muted = playersMuted.contains(uuid);
boolean speaking = !muted && playersSpeaking.contains(uuid);
int mhy = voiceScreenVolumeIndicatorY + voiceScreenVolumeIndicatorH + 33 + i * 9;
boolean hovered = mx >= voiceScreenVolumeIndicatorX - 3 && my >= mhy && mx < voiceScreenVolumeIndicatorX + voiceScreenVolumeIndicatorW + 2 && my < mhy + 9;
float cm = hovered ? 1.5f : 1.0f;
mc.getTextureManager().bindTexture(voiceGuiIcons);
GlStateManager.pushMatrix();
GlStateManager.translate(-100.0f, 115.0f + i * 12.0f, 0.0f);
GlStateManager.scale(0.78f, 0.78f, 0.78f);
if(muted) {
GlStateManager.color(1.0f * cm, 0.2f * cm, 0.2f * cm, 1.0f);
drawTexturedModalRect(0, 0, 64, 208, 16, 16);
}else if(speaking) {
GlStateManager.color(1.0f * cm, 1.0f * cm, 1.0f * cm, 1.0f);
drawTexturedModalRect(0, 0, 64, 176, 16, 16);
}else {
GlStateManager.color(0.65f * cm, 0.65f * cm, 0.65f * cm, 1.0f);
drawTexturedModalRect(0, 0, 64, 144, 16, 16);
}
GlStateManager.popMatrix();
if(muted) {
drawString(fontRendererObj, txt, -84, 117 + i * 12, attenuate(0xCC4444, cm));
}else if(speaking) {
drawString(fontRendererObj, txt, -84, 117 + i * 12, attenuate(0xCCCCCC, cm));
}else {
drawString(fontRendererObj, txt, -84, 117 + i * 12, attenuate(0x999999, cm));
}
}
}else {
txt = "(none)";
drawString(fontRendererObj, txt, -fontRendererObj.getStringWidth(txt), 112, 0xAAAAAA);
}
}else if(status == EnumVoiceChannelStatus.CONNECTING) {
float fadeTimer = MathHelper.sin((float)((System.currentTimeMillis() % 700l) * 0.0014d) * 3.14159f) * 0.35f + 0.3f;
txt = I18n.format("voice.connecting");
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 5, (0xFFDD77 | ((int)(Math.pow(fadeTimer, 1.0d / 2.2d) * 255.0f) << 24)));
GlStateManager.disableBlend();
}else if(status == EnumVoiceChannelStatus.UNAVAILABLE) {
txt = I18n.format("voice.unavailable");
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 5, 0xFF3333);
}else {
flag = true;
}
}
if(flag) {
txt = I18n.format("voice.notConnected");
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 5, 0xBB9999);
}
String OFFstring = I18n.format("voice.off");
String RADIUSstring = I18n.format("voice.radius");
String GLOBALstring = I18n.format("voice.global");
int OFFwidth = fontRendererObj.getStringWidth(OFFstring);
int RADIUSwidth = fontRendererObj.getStringWidth(RADIUSstring);
int GLOBALwidth = fontRendererObj.getStringWidth(GLOBALstring);
voiceButtonOFFposX = 0 - OFFwidth - 8 - RADIUSwidth - 8 - GLOBALwidth;
voiceButtonOFFposY = 20;
voiceButtonOFFposW = OFFwidth + 5;
voiceButtonOFFposH = 15;
voiceScreenButtonOFFposX = voiceButtonOFFposX * 3 / 4 + width - 6;
voiceScreenButtonOFFposY = 15 + (voiceButtonOFFposY + xo) * 3 / 4;
voiceScreenButtonOFFposW = voiceButtonOFFposW * 3 / 4;
voiceScreenButtonOFFposH = voiceButtonOFFposH * 3 / 4;
voiceButtonRADIUSposX = 0 - RADIUSwidth - 8 - GLOBALwidth;
voiceButtonRADIUSposY = 20;
voiceButtonRADIUSposW = RADIUSwidth + 5;
voiceButtonRADIUSposH = 15;
voiceScreenButtonRADIUSposX = voiceButtonRADIUSposX * 3 / 4 + width - 6;
voiceScreenButtonRADIUSposY = 15 + (voiceButtonRADIUSposY + xo) * 3 / 4;
voiceScreenButtonRADIUSposW = voiceButtonRADIUSposW * 3 / 4;
voiceScreenButtonRADIUSposH = voiceButtonRADIUSposH * 3 / 4;
voiceButtonGLOBALposX = 0 - GLOBALwidth;
voiceButtonGLOBALposY = 20;
voiceButtonGLOBALposW = GLOBALwidth + 5;
voiceButtonGLOBALposH = 15;
voiceScreenButtonGLOBALposX = voiceButtonGLOBALposX * 3 / 4 + width - 6;
voiceScreenButtonGLOBALposY = 15 + (voiceButtonGLOBALposY + xo) * 3 / 4;
voiceScreenButtonGLOBALposW = voiceButtonGLOBALposW * 3 / 4;
voiceScreenButtonGLOBALposH = voiceButtonGLOBALposH * 3 / 4;
if(channel == EnumVoiceChannelType.NONE) {
drawOutline(voiceButtonOFFposX, voiceButtonOFFposY, voiceButtonOFFposW, voiceButtonOFFposH, 0xFFCCCCCC);
drawRect(voiceButtonOFFposX + 1, voiceButtonOFFposY + 1, voiceButtonOFFposX + voiceButtonOFFposW - 2,
voiceButtonOFFposY + voiceButtonOFFposH - 1, 0xFF222222);
}else if(mx >= voiceScreenButtonOFFposX && my >= voiceScreenButtonOFFposY && mx < voiceScreenButtonOFFposX +
voiceScreenButtonOFFposW && my < voiceScreenButtonOFFposY + voiceScreenButtonOFFposH) {
drawOutline(voiceButtonOFFposX, voiceButtonOFFposY, voiceButtonOFFposW, voiceButtonOFFposH, 0xFF777777);
}
if(channel == EnumVoiceChannelType.PROXIMITY) {
drawOutline(voiceButtonRADIUSposX, voiceButtonRADIUSposY, voiceButtonRADIUSposW, voiceButtonRADIUSposH, 0xFFCCCCCC);
drawRect(voiceButtonRADIUSposX + 1, voiceButtonRADIUSposY + 1, voiceButtonRADIUSposX + voiceButtonRADIUSposW - 2,
voiceButtonRADIUSposY + voiceButtonRADIUSposH - 1, 0xFF222222);
}else if(mx >= voiceScreenButtonRADIUSposX && my >= voiceScreenButtonRADIUSposY && mx < voiceScreenButtonRADIUSposX +
voiceScreenButtonRADIUSposW && my < voiceScreenButtonRADIUSposY + voiceScreenButtonRADIUSposH) {
drawOutline(voiceButtonRADIUSposX, voiceButtonRADIUSposY, voiceButtonRADIUSposW, voiceButtonRADIUSposH, 0xFF777777);
}
if(channel == EnumVoiceChannelType.GLOBAL) {
drawOutline(voiceButtonGLOBALposX, voiceButtonGLOBALposY, voiceButtonGLOBALposW, voiceButtonGLOBALposH, 0xFFCCCCCC);
drawRect(voiceButtonGLOBALposX + 1, voiceButtonGLOBALposY + 1, voiceButtonGLOBALposX + voiceButtonGLOBALposW - 2,
voiceButtonGLOBALposY + voiceButtonGLOBALposH - 1, 0xFF222222);
}else if(mx >= voiceScreenButtonGLOBALposX && my >= voiceScreenButtonGLOBALposY && mx < voiceScreenButtonGLOBALposX +
voiceScreenButtonGLOBALposW && my < voiceScreenButtonGLOBALposY + voiceScreenButtonGLOBALposH) {
drawOutline(voiceButtonGLOBALposX, voiceButtonGLOBALposY, voiceButtonGLOBALposW, voiceButtonGLOBALposH, 0xFF777777);
}
int enabledColor = (status == EnumVoiceChannelStatus.CONNECTED || channel == EnumVoiceChannelType.NONE) ? 0x66DD66 : 0xDDCC66;
int disabledColor = 0xDD4444;
if(channel != EnumVoiceChannelType.NONE && status == EnumVoiceChannelStatus.UNAVAILABLE) {
enabledColor = disabledColor;
}
drawString(fontRendererObj, OFFstring, 3 - OFFwidth - 8 - RADIUSwidth - 8 - GLOBALwidth, 24, channel == EnumVoiceChannelType.NONE ? enabledColor : disabledColor);
drawString(fontRendererObj, RADIUSstring, 3 - RADIUSwidth - 8 - GLOBALwidth, 24, channel == EnumVoiceChannelType.PROXIMITY ? enabledColor : disabledColor);
drawString(fontRendererObj, GLOBALstring, 3 - GLOBALwidth, 24, channel == EnumVoiceChannelType.GLOBAL ? enabledColor : disabledColor);
GlStateManager.popMatrix();
if(showingCompatWarning) {
drawNotice(I18n.format("voice.unsupportedWarning1"), false, I18n.format("voice.unsupportedWarning2"), I18n.format("voice.unsupportedWarning3"),
"", I18n.format("voice.unsupportedWarning4"), I18n.format("voice.unsupportedWarning5"), I18n.format("voice.unsupportedWarning6"),
I18n.format("voice.unsupportedWarning7"), I18n.format("voice.unsupportedWarning8"), I18n.format("voice.unsupportedWarning9"));
noticeContinueButton.visible = true;
noticeCancelButton.visible = false;
}else if(showingTrackingWarning) {
drawNotice(I18n.format("voice.ipGrabWarning1"), true, I18n.format("voice.ipGrabWarning2"), I18n.format("voice.ipGrabWarning3"),
I18n.format("voice.ipGrabWarning4"), "", I18n.format("voice.ipGrabWarning5"), I18n.format("voice.ipGrabWarning6"),
I18n.format("voice.ipGrabWarning7"), I18n.format("voice.ipGrabWarning8"), I18n.format("voice.ipGrabWarning9"),
I18n.format("voice.ipGrabWarning10"), I18n.format("voice.ipGrabWarning11"), I18n.format("voice.ipGrabWarning12"));
noticeContinueButton.visible = true;
noticeCancelButton.visible = true;
}else {
noticeContinueButton.visible = false;
noticeCancelButton.visible = false;
}
drawButtons(mx, my, partialTicks);
if(showingCompatWarning || showingTrackingWarning) {
throw new AbortedException();
}
}
private void drawNotice(String title, boolean showCancel, String... lines) {
int widthAccum = 0;
for(int i = 0; i < lines.length; ++i) {
int w = fontRendererObj.getStringWidth(lines[i]);
if(widthAccum < w) {
widthAccum = w;
}
}
int margin = 15;
int x = (width - widthAccum) / 2;
int y = (height - lines.length * 10 - 60 - margin) / 2;
drawRect(x - margin - 1, y - margin - 1, x + widthAccum + margin + 1,
y + lines.length * 10 + 49 + margin, 0xFFCCCCCC);
drawRect(x - margin, y - margin, x + widthAccum + margin,
y + lines.length * 10 + 48 + margin, 0xFF111111);
drawCenteredString(fontRendererObj, EnumChatFormatting.BOLD + title, width / 2, y, 0xFF7766);
for(int i = 0; i < lines.length; ++i) {
drawString(fontRendererObj, lines[i], x, y + i * 10 + 18, 0xDDAAAA);
}
if(!showCancel) {
noticeContinueButton.width = 150;
noticeContinueButton.xPosition = (width - 150) / 2;
noticeContinueButton.yPosition = y + lines.length * 10 + 29;
}else {
noticeContinueButton.width = widthAccum / 2 - 10;
noticeContinueButton.xPosition = (width - widthAccum) / 2 + widthAccum / 2 + 3;
noticeContinueButton.yPosition = y + lines.length * 10 + 28;
noticeCancelButton.width = widthAccum / 2 - 10;
noticeCancelButton.xPosition = (width - widthAccum) / 2 + 4;
noticeCancelButton.yPosition = y + lines.length * 10 + 28;
}
}
public static int attenuate(int cin, float f) {
return attenuate(cin, f, f, f, 1.0f);
}
public static int attenuate(int cin, float r, float g, float b, float a) {
float var10 = (float) (cin >> 24 & 255) / 255.0F;
float var6 = (float) (cin >> 16 & 255) / 255.0F;
float var7 = (float) (cin >> 8 & 255) / 255.0F;
float var8 = (float) (cin & 255) / 255.0F;
var10 *= a;
var6 *= r;
var7 *= g;
var8 *= b;
if(var10 > 1.0f) {
var10 = 1.0f;
}
if(var6 > 1.0f) {
var6 = 1.0f;
}
if(var7 > 1.0f) {
var7 = 1.0f;
}
if(var8 > 1.0f) {
var8 = 1.0f;
}
return (((int)(var10 * 255.0f) << 24) | ((int)(var6 * 255.0f) << 16) | ((int)(var7 * 255.0f) << 8) | (int)(var8 * 255.0f));
}
private void drawOutline(int x, int y, int w, int h, int color) {
drawRect(x, y, x + w, y + 1, color);
drawRect(x + w - 1, y + 1, x + w, y + h - 1, color);
drawRect(x, y + h - 1, x + w, y + h, color);
drawRect(x, y + 1, x + 1, y + h - 1, color);
}
public void mouseReleased(int par1, int par2, int par3) {
applyRadiusButton.mouseReleased(par1, par2);
applyVolumeButton.mouseReleased(par1, par2);
noticeContinueButton.mouseReleased(par1, par2);
noticeCancelButton.mouseReleased(par1, par2);
if(showSliderBlocks || showSliderVolume) {
if(showSliderBlocks) {
if(par3 == 0) {
sliderBlocks.mouseReleased(par1, par2);
}
}else if(showSliderVolume) {
if(par3 == 0) {
sliderListenVolume.mouseReleased(par1, par2);
sliderSpeakVolume.mouseReleased(par1, par2);
}
}
throw new AbortedException();
}
}
public void keyTyped(char par1, int par2) {
if(showSliderBlocks || showSliderVolume || showPTTKeyConfig) {
if(showPTTKeyConfig) {
if(par2 == 1) {
showPTTKeyConfig = false;
}else {
mc.gameSettings.voicePTTKey = par2;
showNewPTTKey = 10;
}
}
throw new AbortedException();
}
}
public void mouseClicked(int mx, int my, int button) {
if(showSliderBlocks || showSliderVolume || showPTTKeyConfig || showingCompatWarning || showingTrackingWarning) {
if(showSliderBlocks) {
sliderBlocks.mousePressed(mc, mx, my);
}else if(showSliderVolume) {
sliderListenVolume.mousePressed(mc, mx, my);
sliderSpeakVolume.mousePressed(mc, mx, my);
}
if(button == 0) {
if(applyRadiusButton.mousePressed(mc, mx, my)) actionPerformed(applyRadiusButton);
if(applyVolumeButton.mousePressed(mc, mx, my)) actionPerformed(applyVolumeButton);
if(noticeContinueButton.mousePressed(mc, mx, my)) actionPerformed(noticeContinueButton);
if(noticeCancelButton.mousePressed(mc, mx, my)) actionPerformed(noticeCancelButton);
}
throw new AbortedException();
}
EnumVoiceChannelStatus status = VoiceClientController.getVoiceStatus();
EnumVoiceChannelType channel = VoiceClientController.getVoiceChannel();
if(button == 0) {
if(VoiceClientController.isSupported()) {
if(mx >= voiceScreenButtonOFFposX && my >= voiceScreenButtonOFFposY && mx < voiceScreenButtonOFFposX +
voiceScreenButtonOFFposW && my < voiceScreenButtonOFFposY + voiceScreenButtonOFFposH) {
VoiceClientController.setVoiceChannel(EnumVoiceChannelType.NONE);
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
}else if(mx >= voiceScreenButtonRADIUSposX && my >= voiceScreenButtonRADIUSposY && mx < voiceScreenButtonRADIUSposX +
voiceScreenButtonRADIUSposW && my < voiceScreenButtonRADIUSposY + voiceScreenButtonRADIUSposH) {
if(showCompatWarning) {
continueChannel = EnumVoiceChannelType.PROXIMITY;
showingCompatWarning = true;
}else if(showTrackingWarning) {
continueChannel = EnumVoiceChannelType.PROXIMITY;
showingTrackingWarning = true;
}else {
VoiceClientController.setVoiceChannel(EnumVoiceChannelType.PROXIMITY);
}
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
}else if(mx >= voiceScreenButtonGLOBALposX && my >= voiceScreenButtonGLOBALposY && mx < voiceScreenButtonGLOBALposX +
voiceScreenButtonGLOBALposW && my < voiceScreenButtonGLOBALposY + voiceScreenButtonGLOBALposH) {
if(showCompatWarning) {
continueChannel = EnumVoiceChannelType.GLOBAL;
showingCompatWarning = true;
}else if(showTrackingWarning) {
continueChannel = EnumVoiceChannelType.GLOBAL;
showingTrackingWarning = true;
}else {
VoiceClientController.setVoiceChannel(EnumVoiceChannelType.GLOBAL);
}
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
}else if(channel == EnumVoiceChannelType.PROXIMITY && status == EnumVoiceChannelStatus.CONNECTED && mx >= voiceScreenButtonChangeRadiusposX &&
my >= voiceScreenButtonChangeRadiusposY && mx < voiceScreenButtonChangeRadiusposX + voiceScreenButtonChangeRadiusposW &&
my < voiceScreenButtonChangeRadiusposY + voiceScreenButtonChangeRadiusposH) {
showSliderBlocks = true;
sliderBlocks.sliderValue = (VoiceClientController.getVoiceProximity() - 5) / 17.0f;
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
}else if(status == EnumVoiceChannelStatus.CONNECTED && channel != EnumVoiceChannelType.NONE && mx >= voiceScreenVolumeIndicatorX &&
my >= voiceScreenVolumeIndicatorY && mx < voiceScreenVolumeIndicatorX + voiceScreenVolumeIndicatorW &&
my < voiceScreenVolumeIndicatorY + voiceScreenVolumeIndicatorH) {
showSliderVolume = true;
sliderListenVolume.sliderValue = VoiceClientController.getVoiceListenVolume();
sliderSpeakVolume.sliderValue = VoiceClientController.getVoiceSpeakVolume();
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
}else if(status == EnumVoiceChannelStatus.CONNECTED && channel != EnumVoiceChannelType.NONE && mx >= voiceScreenVolumeIndicatorX - 1 &&
my >= voiceScreenVolumeIndicatorY + voiceScreenVolumeIndicatorH + 2 && mx < voiceScreenVolumeIndicatorX + voiceScreenVolumeIndicatorW + 2 &&
my < voiceScreenVolumeIndicatorY + voiceScreenVolumeIndicatorH + 12) {
showPTTKeyConfig = true;
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
}else if(status == EnumVoiceChannelStatus.CONNECTED) {
List<EaglercraftUUID> playersToRender = VoiceClientController.getVoiceRecent();
if(playersToRender.size() > 0) {
Set<EaglercraftUUID> playersMuted = VoiceClientController.getVoiceMuted();
for(int i = 0, l = playersToRender.size(); i < l; ++i) {
EaglercraftUUID uuid = playersToRender.get(i);
String txt = VoiceClientController.getVoiceUsername(uuid);
boolean muted = playersMuted.contains(uuid);
int mhy = voiceScreenVolumeIndicatorY + voiceScreenVolumeIndicatorH + 33 + i * 9;
if(mx >= voiceScreenVolumeIndicatorX - 3 && my >= mhy && mx < voiceScreenVolumeIndicatorX + voiceScreenVolumeIndicatorW + 2 && my < mhy + 9) {
VoiceClientController.setVoiceMuted(uuid, !muted);
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
break;
}
}
}
}
}
}
}
private void actionPerformed(GuiButton btn) {
if(btn.id == 2) {
showSliderBlocks = false;
VoiceClientController.setVoiceProximity(mc.gameSettings.voiceListenRadius = (int)((sliderBlocks.sliderValue * 17.0f) + 5.0f));
mc.gameSettings.saveOptions();
}else if(btn.id == 3) {
showSliderVolume = false;
VoiceClientController.setVoiceListenVolume(mc.gameSettings.voiceListenVolume = sliderListenVolume.sliderValue);
VoiceClientController.setVoiceSpeakVolume(mc.gameSettings.voiceSpeakVolume = sliderSpeakVolume.sliderValue);
mc.gameSettings.saveOptions();
}else if(btn.id == 4) {
showPTTKeyConfig = false;
mc.gameSettings.saveOptions();
}else if(btn.id == 5) {
if(showingCompatWarning) {
showingCompatWarning = false;
showCompatWarning = false;
if(showTrackingWarning) {
showingTrackingWarning = true;
}else {
VoiceClientController.setVoiceChannel(continueChannel);
}
}else if(showingTrackingWarning) {
showingTrackingWarning = false;
showTrackingWarning = false;
VoiceClientController.setVoiceChannel(continueChannel);
}
}else if(btn.id == 6) {
if(showingTrackingWarning) {
showingTrackingWarning = false;
VoiceClientController.setVoiceChannel(EnumVoiceChannelType.NONE);
}
}
}
public void updateScreen() {
if(showNewPTTKey > 0) {
--showNewPTTKey;
if(showNewPTTKey == 0) {
showPTTKeyConfig = false;
mc.gameSettings.saveOptions();
}
}
}
public boolean isBlockingInput() {
return showSliderBlocks || showSliderVolume || showPTTKeyConfig || showingCompatWarning || showingTrackingWarning;
}
}

View File

@ -0,0 +1,258 @@
package net.lax1dude.eaglercraft.v1_8.voice;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.GL_GREATER;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
import net.lax1dude.eaglercraft.v1_8.Keyboard;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiChat;
import net.minecraft.client.gui.GuiIngameMenu;
import net.minecraft.util.ResourceLocation;
/**
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class GuiVoiceOverlay extends Gui {
public final Minecraft mc;
public int width;
public int height;
private long pttTimer = 0l;
public GuiVoiceOverlay(Minecraft mc) {
this.mc = mc;
}
public void setResolution(int w, int h) {
this.width = w;
this.height = h;
}
private static final ResourceLocation voiceGuiIcons = new ResourceLocation("eagler:gui/eagler_gui.png");
public void drawOverlay() {
if(mc.theWorld != null && VoiceClientController.getVoiceStatus() == EnumVoiceChannelStatus.CONNECTED && VoiceClientController.getVoiceChannel() != EnumVoiceChannelType.NONE &&
!(mc.currentScreen != null && (mc.currentScreen instanceof GuiIngameMenu))) {
if(mc.currentScreen != null && mc.currentScreen.doesGuiPauseGame()) {
return;
}
GlStateManager.disableLighting();
GlStateManager.disableBlend();
GlStateManager.enableAlpha();
GlStateManager.alphaFunc(GL_GREATER, 0.1F);
GlStateManager.pushMatrix();
if(mc.currentScreen == null || (mc.currentScreen instanceof GuiChat)) {
GlStateManager.translate(width / 2 + 77, height - 56, 0.0f);
if(mc.thePlayer == null || mc.thePlayer.capabilities.isCreativeMode) {
GlStateManager.translate(0.0f, 16.0f, 0.0f);
}
}else {
GlStateManager.translate(width / 2 + 10, 4, 0.0f);
}
GlStateManager.scale(0.75f, 0.75f, 0.75f);
String txxt = "press '" + Keyboard.getKeyName(mc.gameSettings.voicePTTKey) + "'";
drawString(mc.fontRendererObj, txxt, -3 - mc.fontRendererObj.getStringWidth(txxt), 9, 0xDDDDDD);
GlStateManager.scale(0.66f, 0.66f, 0.66f);
mc.getTextureManager().bindTexture(voiceGuiIcons);
if((mc.currentScreen == null || !mc.currentScreen.blockPTTKey()) && Keyboard.isKeyDown(mc.gameSettings.voicePTTKey)) {
long millis = System.currentTimeMillis();
if(pttTimer == 0l) {
pttTimer = millis;
}
GlStateManager.color(0.2f, 0.2f, 0.2f, 1.0f);
drawTexturedModalRect(0, 0, 0, 64, 32, 32);
GlStateManager.translate(-1.5f, -1.5f, 0.0f);
if(millis - pttTimer < 1050l) {
if((millis - pttTimer) % 300l < 150l) {
GlStateManager.color(0.9f, 0.2f, 0.2f, 1.0f);
}else {
GlStateManager.color(0.9f, 0.7f, 0.7f, 1.0f);
}
}else {
GlStateManager.color(0.9f, 0.3f, 0.3f, 1.0f);
}
drawTexturedModalRect(0, 0, 0, 64, 32, 32);
}else {
pttTimer = 0l;
GlStateManager.color(0.2f, 0.2f, 0.2f, 1.0f);
drawTexturedModalRect(0, 0, 0, 32, 32, 32);
GlStateManager.translate(-1.5f, -1.5f, 0.0f);
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
drawTexturedModalRect(0, 0, 0, 32, 32, 32);
GlStateManager.translate(-0.5f, -0.5f, 0.0f);
drawTexturedModalRect(0, 0, 0, 32, 32, 32);
}
GlStateManager.popMatrix();
if(VoiceClientController.getVoiceChannel() == EnumVoiceChannelType.PROXIMITY) {
Set<EaglercraftUUID> listeners = VoiceClientController.getVoiceListening();
if(listeners.size() > 0) {
Set<EaglercraftUUID> speakers = VoiceClientController.getVoiceSpeaking();
Set<EaglercraftUUID> muted = VoiceClientController.getVoiceMuted();
List<EaglercraftUUID> listenerList = new ArrayList();
listenerList.addAll(listeners);
listenerList.removeAll(muted);
while(listenerList.size() > 5) {
boolean flag = false;
for(int i = 0, l = listenerList.size(); i < l; ++i) {
if(!speakers.contains(listenerList.get(i))) {
listenerList.remove(i);
flag = true;
break;
}
}
if(!flag) {
break;
}
}
int more = listenerList.size() - 5;
int ww = width;
int hh = height;
if(mc.currentScreen != null && (mc.currentScreen instanceof GuiChat)) {
hh -= 15;
}
List<String> listenerListStr = new ArrayList(Math.min(5, listenerList.size()));
int left = 50;
for(int i = 0, l = listenerList.size(); i < l && i < 5; ++i) {
String txt = VoiceClientController.getVoiceUsername(listenerList.get(i));
listenerListStr.add(txt);
int j = mc.fontRendererObj.getStringWidth(txt) + 4;
if(j > left) {
left = j;
}
}
if(more > 0) {
GlStateManager.pushMatrix();
GlStateManager.translate(ww - left + 3, hh - 10, left);
GlStateManager.scale(0.75f, 0.75f, 0.75f);
drawString(mc.fontRendererObj, "(" + more + " more)", 0, 0, 0xBBBBBB);
GlStateManager.popMatrix();
hh -= 9;
}
for(int i = 0, l = listenerList.size(); i < l && i < 5; ++i) {
boolean speaking = speakers.contains(listenerList.get(i));
float speakf = speaking ? 1.0f : 0.75f;
drawString(mc.fontRendererObj, listenerListStr.get(i), ww - left, hh - 13 - i * 11, speaking ? 0xEEEEEE : 0xBBBBBB);
mc.getTextureManager().bindTexture(voiceGuiIcons);
GlStateManager.pushMatrix();
GlStateManager.translate(ww - left - 14, hh - 14 - i * 11, 0.0f);
GlStateManager.scale(0.75f, 0.75f, 0.75f);
GlStateManager.color(speakf * 0.2f, speakf * 0.2f, speakf * 0.2f, 1.0f);
drawTexturedModalRect(0, 0, 64, speaking ? 176 : 208, 16, 16);
GlStateManager.translate(0.25f, 0.25f, 0.0f);
drawTexturedModalRect(0, 0, 64, speaking ? 176 : 208, 16, 16);
GlStateManager.translate(-1.25f, -1.25f, 0.0f);
GlStateManager.color(speakf, speakf, speakf, 1.0f);
drawTexturedModalRect(0, 0, 64, speaking ? 176 : 208, 16, 16);
GlStateManager.popMatrix();
}
}
}else if(VoiceClientController.getVoiceChannel() == EnumVoiceChannelType.GLOBAL) {
Set<EaglercraftUUID> speakers = VoiceClientController.getVoiceSpeaking();
Set<EaglercraftUUID> muted = VoiceClientController.getVoiceMuted();
List<EaglercraftUUID> listenerList = new ArrayList();
listenerList.addAll(speakers);
listenerList.removeAll(muted);
int more = listenerList.size() - 5;
int ww = width;
int hh = height;
if(mc.currentScreen != null && (mc.currentScreen instanceof GuiChat)) {
hh -= 15;
}
List<String> listenerListStr = new ArrayList(Math.min(5, listenerList.size()));
int left = 50;
for(int i = 0, l = listenerList.size(); i < l && i < 5; ++i) {
String txt = VoiceClientController.getVoiceUsername(listenerList.get(i));
listenerListStr.add(txt);
int j = mc.fontRendererObj.getStringWidth(txt) + 4;
if(j > left) {
left = j;
}
}
if(more > 0) {
GlStateManager.pushMatrix();
GlStateManager.translate(ww - left + 3, hh - 10, left);
GlStateManager.scale(0.75f, 0.75f, 0.75f);
drawString(mc.fontRendererObj, "(" + more + " more)", 0, 0, 0xBBBBBB);
GlStateManager.popMatrix();
hh -= 9;
}
for(int i = 0, l = listenerList.size(); i < l && i < 5; ++i) {
drawString(mc.fontRendererObj, listenerListStr.get(i), ww - left, hh - 13 - i * 11, 0xEEEEEE);
mc.getTextureManager().bindTexture(voiceGuiIcons);
GlStateManager.pushMatrix();
GlStateManager.translate(ww - left - 14, hh - 14 - i * 11, 0.0f);
GlStateManager.scale(0.75f, 0.75f, 0.75f);
GlStateManager.color(0.2f, 0.2f, 0.2f, 1.0f);
drawTexturedModalRect(0, 0, 64, 176, 16, 16);
GlStateManager.translate(0.25f, 0.25f, 0.0f);
drawTexturedModalRect(0, 0, 64, 176, 16, 16);
GlStateManager.translate(-1.25f, -1.25f, 0.0f);
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
drawTexturedModalRect(0, 0, 64, 176, 16, 16);
GlStateManager.popMatrix();
}
}
}
}
}

View File

@ -0,0 +1,367 @@
package net.lax1dude.eaglercraft.v1_8.voice;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
import net.lax1dude.eaglercraft.v1_8.Keyboard;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformVoiceClient;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.profile.EaglerProfile;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.PacketBuffer;
/**
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class VoiceClientController {
public static final String SIGNAL_CHANNEL = "EAG|Voice-1.8";
static final Logger logger = LogManager.getLogger("VoiceClientController");
private static boolean clientSupport = false;
private static boolean serverSupport = false;
private static Consumer<PacketBuffer> packetSendCallback = null;
private static EnumVoiceChannelType voiceChannel = EnumVoiceChannelType.NONE;
private static final HashSet<EaglercraftUUID> nearbyPlayers = new HashSet<>();
private static final ExpiringSet<EaglercraftUUID> recentlyNearbyPlayers = new ExpiringSet<>(5000, uuid -> {
if (!nearbyPlayers.contains(uuid)) {
PlatformVoiceClient.signalDisconnect(uuid, false);
}
});
private static final Map<EaglercraftUUID, String> uuidToNameLookup = new HashMap<>(256);
public static boolean isSupported() {
return isClientSupported() && isServerSupported();
}
private static boolean checked = false;
public static boolean isClientSupported() {
if (!checked) {
checked = true;
clientSupport = EagRuntime.getConfiguration().isAllowVoiceClient() && PlatformVoiceClient.isSupported();
}
return clientSupport;
}
public static boolean isServerSupported() {
return serverSupport;
}
public static void initializeVoiceClient(Consumer<PacketBuffer> signalSendCallbackIn) {
packetSendCallback = signalSendCallbackIn;
uuidToNameLookup.clear();
if (getVoiceChannel() != EnumVoiceChannelType.NONE) sendInitialVoice();
}
public static void handleVoiceSignalPacket(PacketBuffer packetData) {
VoiceSignalPackets.handleVoiceSignal(packetData);
}
static void handleVoiceSignalPacketTypeGlobal(EaglercraftUUID[] voicePlayers, String[] voiceNames) {
uuidToNameLookup.clear();
for (int i = 0; i < voicePlayers.length; i++) {
if(voiceNames != null) {
uuidToNameLookup.put(voicePlayers[i], voiceNames[i]);
}
sendPacketRequestIfNeeded(voicePlayers[i]);
}
}
public static void handleServerDisconnect() {
if(!isClientSupported()) return;
serverSupport = false;
uuidToNameLookup.clear();
for (EaglercraftUUID uuid : nearbyPlayers) {
PlatformVoiceClient.signalDisconnect(uuid, false);
}
for (EaglercraftUUID uuid : recentlyNearbyPlayers) {
PlatformVoiceClient.signalDisconnect(uuid, false);
}
nearbyPlayers.clear();
recentlyNearbyPlayers.clear();
Set<EaglercraftUUID> antiConcurrentModificationUUIDs = new HashSet<>(listeningSet);
for (EaglercraftUUID uuid : antiConcurrentModificationUUIDs) {
PlatformVoiceClient.signalDisconnect(uuid, false);
}
activateVoice(false);
}
static void handleVoiceSignalPacketTypeAllowed(boolean voiceAvailableStat, String[] servs) {
serverSupport = voiceAvailableStat;
PlatformVoiceClient.setICEServers(servs);
if(isSupported()) {
EnumVoiceChannelType ch = getVoiceChannel();
setVoiceChannel(EnumVoiceChannelType.NONE);
setVoiceChannel(ch);
}
}
static void handleVoiceSignalPacketTypeConnect(EaglercraftUUID user, boolean offer) {
PlatformVoiceClient.signalConnect(user, offer);
}
static void handleVoiceSignalPacketTypeConnectAnnounce(EaglercraftUUID user) {
sendPacketRequest(user);
}
static void handleVoiceSignalPacketTypeDisconnect(EaglercraftUUID user) {
PlatformVoiceClient.signalDisconnect(user, true);
}
static void handleVoiceSignalPacketTypeICECandidate(EaglercraftUUID user, String ice) {
PlatformVoiceClient.signalICECandidate(user, ice);
}
static void handleVoiceSignalPacketTypeDescription(EaglercraftUUID user, String desc) {
PlatformVoiceClient.signalDescription(user, desc);
}
public static void tickVoiceClient(Minecraft mc) {
if(!isClientSupported()) return;
recentlyNearbyPlayers.checkForExpirations();
speakingSet.clear();
PlatformVoiceClient.tickVoiceClient();
if (getVoiceChannel() != EnumVoiceChannelType.NONE && (getVoiceStatus() == EnumVoiceChannelStatus.CONNECTING || getVoiceStatus() == EnumVoiceChannelStatus.CONNECTED)) {
activateVoice((mc.currentScreen == null || !mc.currentScreen.blockPTTKey()) && Keyboard.isKeyDown(mc.gameSettings.voicePTTKey));
if (mc.theWorld != null && mc.thePlayer != null) {
HashSet<EaglercraftUUID> seenPlayers = new HashSet<>();
for (EntityPlayer player : mc.theWorld.playerEntities) {
if (player == mc.thePlayer) continue;
if (getVoiceChannel() == EnumVoiceChannelType.PROXIMITY) updateVoicePosition(player.getUniqueID(), player.posX, player.posY + player.getEyeHeight(), player.posZ);
int prox = 22;
// cube
if (Math.abs(mc.thePlayer.posX - player.posX) <= prox && Math.abs(mc.thePlayer.posY - player.posY) <= prox && Math.abs(mc.thePlayer.posZ - player.posZ) <= prox) {
if (!uuidToNameLookup.containsKey(player.getUniqueID())) {
uuidToNameLookup.put(player.getUniqueID(), player.getName());
}
if (addNearbyPlayer(player.getUniqueID())) {
seenPlayers.add(player.getUniqueID());
}
}
}
cleanupNearbyPlayers(seenPlayers);
}
}
}
public static final boolean addNearbyPlayer(EaglercraftUUID uuid) {
recentlyNearbyPlayers.remove(uuid);
if (nearbyPlayers.add(uuid)) {
sendPacketRequestIfNeeded(uuid);
return true;
}
return false;
}
public static final void removeNearbyPlayer(EaglercraftUUID uuid) {
if (nearbyPlayers.remove(uuid)) {
if (getVoiceStatus() == EnumVoiceChannelStatus.DISCONNECTED || getVoiceStatus() == EnumVoiceChannelStatus.UNAVAILABLE) return;
if (voiceChannel == EnumVoiceChannelType.PROXIMITY) recentlyNearbyPlayers.add(uuid);
}
}
public static final void cleanupNearbyPlayers(HashSet<EaglercraftUUID> existingPlayers) {
nearbyPlayers.stream().filter(ud -> !existingPlayers.contains(ud)).collect(Collectors.toSet()).forEach(VoiceClientController::removeNearbyPlayer);
}
public static final void updateVoicePosition(EaglercraftUUID uuid, double x, double y, double z) {
PlatformVoiceClient.updateVoicePosition(uuid, x, y, z);
}
public static void setVoiceChannel(EnumVoiceChannelType channel) {
if (voiceChannel == channel) return;
if (channel != EnumVoiceChannelType.NONE) PlatformVoiceClient.initializeDevices();
PlatformVoiceClient.resetPeerStates();
if (channel == EnumVoiceChannelType.NONE) {
for (EaglercraftUUID uuid : nearbyPlayers) {
PlatformVoiceClient.signalDisconnect(uuid, false);
}
for (EaglercraftUUID uuid : recentlyNearbyPlayers) {
PlatformVoiceClient.signalDisconnect(uuid, false);
}
nearbyPlayers.clear();
recentlyNearbyPlayers.clear();
Set<EaglercraftUUID> antiConcurrentModificationUUIDs = new HashSet<>(listeningSet);
for (EaglercraftUUID uuid : antiConcurrentModificationUUIDs) {
PlatformVoiceClient.signalDisconnect(uuid, false);
}
sendPacketDisconnect(null);
activateVoice(false);
} else if (voiceChannel == EnumVoiceChannelType.PROXIMITY) {
for (EaglercraftUUID uuid : nearbyPlayers) {
PlatformVoiceClient.signalDisconnect(uuid, false);
}
for (EaglercraftUUID uuid : recentlyNearbyPlayers) {
PlatformVoiceClient.signalDisconnect(uuid, false);
}
nearbyPlayers.clear();
recentlyNearbyPlayers.clear();
sendPacketDisconnect(null);
} else if(voiceChannel == EnumVoiceChannelType.GLOBAL) {
Set<EaglercraftUUID> antiConcurrentModificationUUIDs = new HashSet<>(listeningSet);
antiConcurrentModificationUUIDs.removeAll(nearbyPlayers);
antiConcurrentModificationUUIDs.removeAll(recentlyNearbyPlayers);
for (EaglercraftUUID uuid : antiConcurrentModificationUUIDs) {
PlatformVoiceClient.signalDisconnect(uuid, false);
}
sendPacketDisconnect(null);
}
voiceChannel = channel;
if (channel != EnumVoiceChannelType.NONE) {
sendInitialVoice();
}
}
public static void sendInitialVoice() {
sendPacketConnect();
for (EaglercraftUUID uuid : nearbyPlayers) {
sendPacketRequest(uuid);
}
}
public static EnumVoiceChannelType getVoiceChannel() {
return voiceChannel;
}
private static boolean voicePeerErrored() {
return PlatformVoiceClient.getPeerState() == EnumVoiceChannelPeerState.FAILED || PlatformVoiceClient.getPeerStateConnect() == EnumVoiceChannelPeerState.FAILED || PlatformVoiceClient.getPeerStateInitial() == EnumVoiceChannelPeerState.FAILED || PlatformVoiceClient.getPeerStateDesc() == EnumVoiceChannelPeerState.FAILED || PlatformVoiceClient.getPeerStateIce() == EnumVoiceChannelPeerState.FAILED;
}
public static EnumVoiceChannelStatus getVoiceStatus() {
return (!isClientSupported() || !isServerSupported()) ? EnumVoiceChannelStatus.UNAVAILABLE :
(PlatformVoiceClient.getReadyState() != EnumVoiceChannelReadyState.DEVICE_INITIALIZED ?
EnumVoiceChannelStatus.CONNECTING : (voicePeerErrored() ? EnumVoiceChannelStatus.UNAVAILABLE : EnumVoiceChannelStatus.CONNECTED));
}
private static boolean talkStatus = false;
public static void activateVoice(boolean talk) {
if (talkStatus != talk) {
PlatformVoiceClient.activateVoice(talk);
talkStatus = talk;
}
}
private static int proximity = 16;
public static void setVoiceProximity(int prox) {
PlatformVoiceClient.setVoiceProximity(prox);
proximity = prox;
}
public static int getVoiceProximity() {
return proximity;
}
private static float volumeListen = 0.5f;
public static void setVoiceListenVolume(float f) {
PlatformVoiceClient.setVoiceListenVolume(f);
volumeListen = f;
}
public static float getVoiceListenVolume() {
return volumeListen;
}
private static float volumeSpeak = 0.5f;
public static void setVoiceSpeakVolume(float f) {
if (volumeSpeak != f) {
PlatformVoiceClient.setMicVolume(f);
}
volumeSpeak = f;
}
public static float getVoiceSpeakVolume() {
return volumeSpeak;
}
private static final Set<EaglercraftUUID> listeningSet = new HashSet<>();
private static final Set<EaglercraftUUID> speakingSet = new HashSet<>();
private static final Set<EaglercraftUUID> mutedSet = new HashSet<>();
public static Set<EaglercraftUUID> getVoiceListening() {
return listeningSet;
}
public static Set<EaglercraftUUID> getVoiceSpeaking() {
return speakingSet;
}
public static void setVoiceMuted(EaglercraftUUID uuid, boolean mute) {
PlatformVoiceClient.mutePeer(uuid, mute);
if (mute) {
mutedSet.add(uuid);
} else {
mutedSet.remove(uuid);
}
}
public static Set<EaglercraftUUID> getVoiceMuted() {
return mutedSet;
}
public static List<EaglercraftUUID> getVoiceRecent() {
return new ArrayList<>(listeningSet);
}
public static String getVoiceUsername(EaglercraftUUID uuid) {
if(uuid == null) {
return "null";
}
String ret = uuidToNameLookup.get(uuid);
return ret == null ? uuid.toString() : ret;
}
public static void sendPacketICE(EaglercraftUUID peerId, String candidate) {
packetSendCallback.accept(VoiceSignalPackets.makeVoiceSignalPacketICE(peerId, candidate));
}
public static void sendPacketDesc(EaglercraftUUID peerId, String desc) {
packetSendCallback.accept(VoiceSignalPackets.makeVoiceSignalPacketDesc(peerId, desc));
}
public static void sendPacketDisconnect(EaglercraftUUID peerId) {
packetSendCallback.accept(VoiceSignalPackets.makeVoiceSignalPacketDisconnect(peerId));
}
public static void sendPacketConnect() {
packetSendCallback.accept(VoiceSignalPackets.makeVoiceSignalPacketConnect());
}
public static void sendPacketRequest(EaglercraftUUID peerId) {
packetSendCallback.accept(VoiceSignalPackets.makeVoiceSignalPacketRequest(peerId));
}
private static void sendPacketRequestIfNeeded(EaglercraftUUID uuid) {
if (getVoiceStatus() == EnumVoiceChannelStatus.DISCONNECTED || getVoiceStatus() == EnumVoiceChannelStatus.UNAVAILABLE) return;
if(uuid.equals(EaglerProfile.getPlayerUUID())) return;
if (!getVoiceListening().contains(uuid)) sendPacketRequest(uuid);
}
}

View File

@ -0,0 +1,142 @@
package net.lax1dude.eaglercraft.v1_8.voice;
import java.nio.charset.StandardCharsets;
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
import net.lax1dude.eaglercraft.v1_8.netty.Unpooled;
import net.minecraft.network.PacketBuffer;
/**
* Copyright (c) 2024 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class VoiceSignalPackets {
static final int VOICE_SIGNAL_ALLOWED = 0;
static final int VOICE_SIGNAL_REQUEST = 0;
static final int VOICE_SIGNAL_CONNECT = 1;
static final int VOICE_SIGNAL_DISCONNECT = 2;
static final int VOICE_SIGNAL_ICE = 3;
static final int VOICE_SIGNAL_DESC = 4;
static final int VOICE_SIGNAL_GLOBAL = 5;
static void handleVoiceSignal(PacketBuffer streamIn) {
try {
int sig = streamIn.readUnsignedByte();
switch(sig) {
case VOICE_SIGNAL_ALLOWED: {
boolean voiceAvailableStat = streamIn.readUnsignedByte() == 1;
String[] servs = null;
if(voiceAvailableStat) {
servs = new String[streamIn.readVarIntFromBuffer()];
for(int i = 0; i < servs.length; i++) {
servs[i] = streamIn.readStringFromBuffer(1024);
}
}
VoiceClientController.handleVoiceSignalPacketTypeAllowed(voiceAvailableStat, servs);
break;
}
case VOICE_SIGNAL_GLOBAL: {
if (VoiceClientController.getVoiceChannel() != EnumVoiceChannelType.GLOBAL) return;
EaglercraftUUID[] voiceIds = new EaglercraftUUID[streamIn.readVarIntFromBuffer()];
for(int i = 0; i < voiceIds.length; i++) {
voiceIds[i] = streamIn.readUuid();
}
String[] voiceNames = null;
if (streamIn.isReadable()) {
voiceNames = new String[voiceIds.length];
for(int i = 0; i < voiceNames.length; i++) {
voiceNames[i] = streamIn.readStringFromBuffer(16);
}
}
VoiceClientController.handleVoiceSignalPacketTypeGlobal(voiceIds, voiceNames);
break;
}
case VOICE_SIGNAL_CONNECT: {
EaglercraftUUID uuid = streamIn.readUuid();
if (streamIn.isReadable()) {
VoiceClientController.handleVoiceSignalPacketTypeConnect(uuid, streamIn.readBoolean());
} else if (VoiceClientController.getVoiceChannel() != EnumVoiceChannelType.PROXIMITY || VoiceClientController.getVoiceListening().contains(uuid)) {
VoiceClientController.handleVoiceSignalPacketTypeConnectAnnounce(uuid);
}
break;
}
case VOICE_SIGNAL_DISCONNECT: {
VoiceClientController.handleVoiceSignalPacketTypeDisconnect(streamIn.readableBytes() > 0 ? streamIn.readUuid() : null);
break;
}
case VOICE_SIGNAL_ICE: {
VoiceClientController.handleVoiceSignalPacketTypeICECandidate(streamIn.readUuid(), streamIn.readStringFromBuffer(32767));
break;
}
case VOICE_SIGNAL_DESC: {
VoiceClientController.handleVoiceSignalPacketTypeDescription(streamIn.readUuid(), streamIn.readStringFromBuffer(32767));
break;
}
default: {
VoiceClientController.logger.error("Unknown voice signal packet '{}'!", sig);
break;
}
}
}catch(Throwable ex) {
VoiceClientController.logger.error("Failed to handle signal packet!");
VoiceClientController.logger.error(ex);
}
}
static PacketBuffer makeVoiceSignalPacketRequest(EaglercraftUUID user) {
PacketBuffer ret = new PacketBuffer(Unpooled.buffer(17, 17));
ret.writeByte(VOICE_SIGNAL_REQUEST);
ret.writeUuid(user);
return ret;
}
static PacketBuffer makeVoiceSignalPacketICE(EaglercraftUUID user, String icePacket) {
byte[] str = icePacket.getBytes(StandardCharsets.UTF_8);
int estLen = 17 + PacketBuffer.getVarIntSize(str.length) + str.length;
PacketBuffer ret = new PacketBuffer(Unpooled.buffer(estLen, estLen));
ret.writeByte(VOICE_SIGNAL_ICE);
ret.writeUuid(user);
ret.writeByteArray(str);
return ret;
}
static PacketBuffer makeVoiceSignalPacketDesc(EaglercraftUUID user, String descPacket) {
byte[] str = descPacket.getBytes(StandardCharsets.UTF_8);
int estLen = 17 + PacketBuffer.getVarIntSize(str.length) + str.length;
PacketBuffer ret = new PacketBuffer(Unpooled.buffer(estLen, estLen));
ret.writeByte(VOICE_SIGNAL_DESC);
ret.writeUuid(user);
ret.writeByteArray(str);
return ret;
}
static PacketBuffer makeVoiceSignalPacketDisconnect(EaglercraftUUID user) {
if (user == null) {
PacketBuffer ret = new PacketBuffer(Unpooled.buffer(1, 1));
ret.writeByte(VOICE_SIGNAL_DISCONNECT);
return ret;
}
PacketBuffer ret = new PacketBuffer(Unpooled.buffer(17, 17));
ret.writeByte(VOICE_SIGNAL_DISCONNECT);
ret.writeUuid(user);
return ret;
}
public static PacketBuffer makeVoiceSignalPacketConnect() {
PacketBuffer ret = new PacketBuffer(Unpooled.buffer(1, 1));
ret.writeByte(VOICE_SIGNAL_CONNECT);
return ret;
}
}

View File

@ -0,0 +1,118 @@
package net.lax1dude.eaglercraft.v1_8.voice;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import java.util.HashSet;
import java.util.Set;
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.lax1dude.eaglercraft.v1_8.opengl.WorldRenderer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityOtherPlayerMP;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
/**
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class VoiceTagRenderer {
private static final ResourceLocation voiceGuiIcons = new ResourceLocation("eagler:gui/eagler_gui.png");
private static final Set<EaglercraftUUID> voiceTagsDrawnThisFrame = new HashSet();
public static void renderVoiceNameTag(Minecraft mc, EntityOtherPlayerMP player, int offset) {
EaglercraftUUID uuid = player.getUniqueID();
boolean mute = VoiceClientController.getVoiceMuted().contains(uuid);
if((mute || VoiceClientController.getVoiceSpeaking().contains(uuid)) && voiceTagsDrawnThisFrame.add(uuid)) {
GlStateManager.disableLighting();
GlStateManager.disableTexture2D();
GlStateManager.enableAlpha();
GlStateManager.depthMask(false);
GlStateManager.disableDepth();
GlStateManager.enableBlend();
GlStateManager.pushMatrix();
GlStateManager.translate(-8.0f, -18.0f + offset, 0.0f);
GlStateManager.scale(16.0f, 16.0f, 16.0f);
Tessellator tessellator = Tessellator.getInstance();
WorldRenderer worldrenderer = tessellator.getWorldRenderer();
worldrenderer.begin(7, DefaultVertexFormats.POSITION_COLOR);
float a = 0.25F;
worldrenderer.pos(-0.02, -0.02, 0.0).color(0.0F, 0.0F, 0.0F, a).endVertex();
worldrenderer.pos(-0.02, 1.02, 0.0).color(0.0F, 0.0F, 0.0F, a).endVertex();
worldrenderer.pos(1.02, 1.02, 0.0).color(0.0F, 0.0F, 0.0F, a).endVertex();
worldrenderer.pos(1.02, -0.02, 0.0).color(0.0F, 0.0F, 0.0F, a).endVertex();
tessellator.draw();
GlStateManager.enableTexture2D();
GlStateManager.enableAlpha();
GlStateManager.alphaFunc(GL_GREATER, 0.02f);
mc.getTextureManager().bindTexture(voiceGuiIcons);
int u = 0;
int v = mute ? 192 : 160;
float var7 = 0.00390625F;
float var8 = 0.00390625F;
if(mute) {
GlStateManager.color(0.9F, 0.3F, 0.3F, 0.125F);
}else {
GlStateManager.color(1.0F, 1.0F, 1.0F, 0.125F);
}
worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX);
worldrenderer.pos(0, 1.0, 0).tex((double) ((float) (u + 0.2f) * var7), (double) ((float) (v + 32 - 0.2f) * var8)).endVertex();
worldrenderer.pos(1.0, 1.0, 0).tex((double) ((float) (u + 32 - 0.2f) * var7), (double) ((float) (v + 32 - 0.2f) * var8)).endVertex();
worldrenderer.pos(1.0, 0, 0).tex((double) ((float) (u + 32 - 0.2f) * var7), (double) ((float) (v + 0.2f) * var8)).endVertex();
worldrenderer.pos(0, 0, 0).tex((double) ((float) (u + 0.2f) * var7), (double) ((float) (v + 0.2f) * var8)).endVertex();
tessellator.draw();
GlStateManager.alphaFunc(GL_GREATER, 0.1f);
GlStateManager.enableDepth();
GlStateManager.depthMask(true);
if(mute) {
GlStateManager.color(0.9F, 0.3F, 0.3F, 1.0F);
}else {
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
}
worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX);
worldrenderer.pos(0, 1.0, 0).tex((double) ((float) (u + 0.2f) * var7), (double) ((float) (v + 32 - 0.2f) * var8)).endVertex();
worldrenderer.pos(1.0, 1.0, 0).tex((double) ((float) (u + 32 - 0.2f) * var7), (double) ((float) (v + 32 - 0.2f) * var8)).endVertex();
worldrenderer.pos(1.0, 0, 0).tex((double) ((float) (u + 32 - 0.2f) * var7), (double) ((float) (v + 0.2f) * var8)).endVertex();
worldrenderer.pos(0, 0, 0).tex((double) ((float) (u + 0.2f) * var7), (double) ((float) (v + 0.2f) * var8)).endVertex();
tessellator.draw();
GlStateManager.enableLighting();
GlStateManager.disableBlend();
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
GlStateManager.popMatrix();
}
}
public static void clearTagsDrawnSet() {
voiceTagsDrawnThisFrame.clear();
}
}