mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-27 18:38:14 -05:00
Update #28 - Added capes, voice chat, FNAW skins, and fixes
This commit is contained in:
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user