forked from SteamWar/SteamWar
Add Advancement
Add Advancements Add AdvancementsManager Add SelectAdvancementTabPacket Add item.json Update ConnectionListener
This commit is contained in:
@@ -0,0 +1,286 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.velocitycore.advancements;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
|
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||||
|
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||||
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
|
||||||
|
import de.steamwar.messages.Chatter;
|
||||||
|
import de.steamwar.sql.SteamwarUser;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.ToString;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class Advancement {
|
||||||
|
|
||||||
|
{
|
||||||
|
Advancements.all.add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final Map<SteamwarUser, Advancement.Data> data = new HashMap<>();
|
||||||
|
|
||||||
|
public Advancement.Data get(SteamwarUser user) {
|
||||||
|
return get(user, Data::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Advancement.Data get(SteamwarUser user, BiFunction<Advancement, SteamwarUser, Data> function) {
|
||||||
|
if (data.containsKey(user)) return data.get(user);
|
||||||
|
return function.apply(this, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String identifier;
|
||||||
|
private final Optional<Advancement> parent;
|
||||||
|
private final Display display;
|
||||||
|
|
||||||
|
private final HidePolicy hidePolicy;
|
||||||
|
private final int total;
|
||||||
|
|
||||||
|
private final Function<SteamwarUser, Integer> progressCalculator;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder st = new StringBuilder();
|
||||||
|
st.append("Advancement(");
|
||||||
|
parent.ifPresent(advancement -> st.append(advancement.identifier).append("<-"));
|
||||||
|
st.append(identifier);
|
||||||
|
st.append(", total=").append(total);
|
||||||
|
st.append(")");
|
||||||
|
return st.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class Display {
|
||||||
|
private final Component title;
|
||||||
|
private final Component description;
|
||||||
|
private final String item;
|
||||||
|
private final FrameType frameType;
|
||||||
|
private Optional<String> background = Optional.empty();
|
||||||
|
private final float xCoord;
|
||||||
|
private final float yCoord;
|
||||||
|
|
||||||
|
public enum FrameType {
|
||||||
|
TASK,
|
||||||
|
CHALLENGE,
|
||||||
|
GOAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum HidePolicy {
|
||||||
|
NEVER {
|
||||||
|
@Override
|
||||||
|
public boolean hidden(Data data) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
NO_PROGRESS {
|
||||||
|
@Override
|
||||||
|
public boolean hidden(Data data) {
|
||||||
|
return data.progress == 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
PREVIOUS_UNFINISHED {
|
||||||
|
@Override
|
||||||
|
public boolean hidden(Data data) {
|
||||||
|
if (data.advancement.parent.isPresent()) {
|
||||||
|
Advancement parent = data.advancement.parent.get();
|
||||||
|
Advancement.Data parentData = parent.get(data.user);
|
||||||
|
return parentData.progress != parentData.advancement.total;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public abstract boolean hidden(Data data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ToString
|
||||||
|
public static class Data {
|
||||||
|
private final Advancement advancement;
|
||||||
|
private final SteamwarUser user;
|
||||||
|
|
||||||
|
private int progress;
|
||||||
|
private boolean showToast = true;
|
||||||
|
private boolean hidden = false;
|
||||||
|
|
||||||
|
public Data(Advancement advancement, SteamwarUser user) {
|
||||||
|
this.advancement = advancement;
|
||||||
|
advancement.data.put(user, this);
|
||||||
|
this.user = user;
|
||||||
|
this.progress = advancement.progressCalculator.apply(user);
|
||||||
|
checkHidden();
|
||||||
|
checkFinished();
|
||||||
|
new Packet(this, showToast).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Data(Advancement advancement, SteamwarUser user, int progress) {
|
||||||
|
this.advancement = advancement;
|
||||||
|
advancement.data.put(user, this);
|
||||||
|
this.user = user;
|
||||||
|
this.progress = progress;
|
||||||
|
checkHidden();
|
||||||
|
checkFinished();
|
||||||
|
new Packet(this, showToast).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
this.progress = advancement.progressCalculator.apply(user);
|
||||||
|
checkHidden();
|
||||||
|
|
||||||
|
new Packet(this, showToast).send();
|
||||||
|
// Update Advancements that have this as parent
|
||||||
|
Advancements.getAll()
|
||||||
|
.stream()
|
||||||
|
.filter(advancement -> advancement.parent.filter(value -> value == this.advancement).isPresent())
|
||||||
|
.map(advancement -> advancement.get(user))
|
||||||
|
.forEach(Advancement.Data::update);
|
||||||
|
|
||||||
|
checkFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkHidden() {
|
||||||
|
hidden = advancement.hidePolicy.hidden(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkFinished() {
|
||||||
|
if (progress == advancement.total) {
|
||||||
|
showToast = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final JsonObject ITEMS = new Gson().fromJson(new BufferedReader(new InputStreamReader(Advancement.class.getResourceAsStream("/de/steamwar/velocitycore/advancements/item.json"))), JsonObject.class);
|
||||||
|
|
||||||
|
private void encodeAdvancement(ByteBuf byteBuf, ProtocolVersion protocolVersion, boolean showToast) {
|
||||||
|
ProtocolUtils.writeString(byteBuf, advancement.identifier);
|
||||||
|
if (advancement.parent.isPresent()) {
|
||||||
|
byteBuf.writeBoolean(true);
|
||||||
|
ProtocolUtils.writeString(byteBuf, advancement.parent.get().identifier);
|
||||||
|
} else {
|
||||||
|
byteBuf.writeBoolean(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Display
|
||||||
|
byteBuf.writeBoolean(true);
|
||||||
|
new ComponentHolder(protocolVersion, advancement.display.title).write(byteBuf);
|
||||||
|
new ComponentHolder(protocolVersion, advancement.display.description).write(byteBuf);
|
||||||
|
{ // Slot
|
||||||
|
ProtocolUtils.writeVarInt(byteBuf, 1);
|
||||||
|
int itemId = ITEMS.get(protocolVersion.name().replace("MINECRAFT_", "V_"))
|
||||||
|
.getAsJsonObject()
|
||||||
|
.get(advancement.display.item)
|
||||||
|
.getAsInt();
|
||||||
|
ProtocolUtils.writeVarInt(byteBuf, itemId);
|
||||||
|
ProtocolUtils.writeVarInt(byteBuf, 0);
|
||||||
|
ProtocolUtils.writeVarInt(byteBuf, 0);
|
||||||
|
}
|
||||||
|
ProtocolUtils.writeVarInt(byteBuf, advancement.display.frameType.ordinal());
|
||||||
|
if (advancement.display.background.isPresent()) {
|
||||||
|
byteBuf.writeInt(0x01 | (showToast ? 0x02 : 0x00) | (hidden ? 0x04 : 0x00));
|
||||||
|
ProtocolUtils.writeString(byteBuf, advancement.display.background.get());
|
||||||
|
} else {
|
||||||
|
byteBuf.writeInt((showToast ? 0x02 : 0x00) | (hidden ? 0x04 : 0x00));
|
||||||
|
}
|
||||||
|
byteBuf.writeFloat(advancement.display.xCoord);
|
||||||
|
byteBuf.writeFloat(advancement.display.yCoord);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProtocolUtils.writeVarInt(byteBuf, advancement.total);
|
||||||
|
for (int i = 0; i < advancement.total; i++) {
|
||||||
|
ProtocolUtils.writeVarInt(byteBuf, 1);
|
||||||
|
ProtocolUtils.writeString(byteBuf, advancement.identifier + "_" + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
byteBuf.writeBoolean(false); // No Telemetry
|
||||||
|
}
|
||||||
|
|
||||||
|
private void encodeProgress(ByteBuf byteBuf) {
|
||||||
|
ProtocolUtils.writeString(byteBuf, this.advancement.identifier);
|
||||||
|
ProtocolUtils.writeVarInt(byteBuf, advancement.total);
|
||||||
|
for (int i = 0; i < advancement.total; i++) {
|
||||||
|
ProtocolUtils.writeString(byteBuf, advancement.identifier + "_" + i);
|
||||||
|
if (i == advancement.total - 1 && advancement.total == progress) {
|
||||||
|
byteBuf.writeBoolean(true);
|
||||||
|
byteBuf.writeLong(new Date().getTime());
|
||||||
|
} else if (i < progress) {
|
||||||
|
byteBuf.writeBoolean(true);
|
||||||
|
byteBuf.writeLong(0);
|
||||||
|
} else {
|
||||||
|
byteBuf.writeBoolean(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected record Packet(Data data, boolean showToast) implements MinecraftPacket {
|
||||||
|
public void send() {
|
||||||
|
Player player = Chatter.of(data.user).getPlayer();
|
||||||
|
((ConnectedPlayer) player).getConnection().write(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decode(ByteBuf byteBuf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf byteBuf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
|
||||||
|
byteBuf.writeBoolean(false); // Clear
|
||||||
|
|
||||||
|
if (!data.hidden) {
|
||||||
|
ProtocolUtils.writeVarInt(byteBuf, 1);
|
||||||
|
data.encodeAdvancement(byteBuf, protocolVersion, showToast);
|
||||||
|
ProtocolUtils.writeVarInt(byteBuf, 0); // No Advancements to remove
|
||||||
|
ProtocolUtils.writeVarInt(byteBuf, 1);
|
||||||
|
data.encodeProgress(byteBuf);
|
||||||
|
} else {
|
||||||
|
ProtocolUtils.writeVarInt(byteBuf, 0); // No Advancements to update
|
||||||
|
ProtocolUtils.writeVarInt(byteBuf, 1);
|
||||||
|
ProtocolUtils.writeString(byteBuf, data.advancement.identifier);
|
||||||
|
ProtocolUtils.writeVarInt(byteBuf, 0); // No Advancements Progress to update
|
||||||
|
}
|
||||||
|
|
||||||
|
byteBuf.writeBoolean(true); // Show Advancements
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(MinecraftSessionHandler minecraftSessionHandler) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.velocitycore.advancements;
|
||||||
|
|
||||||
|
import de.steamwar.messages.Chatter;
|
||||||
|
import de.steamwar.persistent.Storage;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public class Advancements {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
static final List<Advancement> all = new ArrayList<>();
|
||||||
|
|
||||||
|
public static final Advancement ROOT = new Advancement(
|
||||||
|
"steamwar:advancements/root",
|
||||||
|
Optional.empty(),
|
||||||
|
new Advancement.Display(
|
||||||
|
Component.text("SteamWar"),
|
||||||
|
Component.text("Join SteamWar for the first time!"),
|
||||||
|
"cactus_flower",
|
||||||
|
Advancement.Display.FrameType.CHALLENGE,
|
||||||
|
Optional.of("minecraft:gui/advancements/backgrounds/adventure"),
|
||||||
|
0f,
|
||||||
|
0f
|
||||||
|
),
|
||||||
|
Advancement.HidePolicy.NEVER,
|
||||||
|
1,
|
||||||
|
user -> 1
|
||||||
|
);
|
||||||
|
|
||||||
|
static {
|
||||||
|
Advancement previous = ROOT;
|
||||||
|
int[] playTimes = new int[]{1, 10, 100, 500, 1000, 2500, 5000, 7500, 10000, 15000, 20000};
|
||||||
|
for (int i = 0; i < playTimes.length; i++) {
|
||||||
|
int neededPlayTime = playTimes[i];
|
||||||
|
previous = new Advancement(
|
||||||
|
"steamwar:advancements/playtime_" + neededPlayTime + "_hour",
|
||||||
|
Optional.of(previous),
|
||||||
|
new Advancement.Display(
|
||||||
|
Component.text("Play " + neededPlayTime + " Hour" + (neededPlayTime > 1 ? "s" : "")),
|
||||||
|
Component.text("Play " + neededPlayTime + " hour" + (neededPlayTime > 1 ? "s" : "") + " on SteamWar"),
|
||||||
|
"clock",
|
||||||
|
Advancement.Display.FrameType.TASK,
|
||||||
|
i + 1f,
|
||||||
|
0f
|
||||||
|
),
|
||||||
|
Advancement.HidePolicy.PREVIOUS_UNFINISHED,
|
||||||
|
Math.min(neededPlayTime, 100),
|
||||||
|
user -> {
|
||||||
|
double playtime = user.getOnlinetime();
|
||||||
|
playtime += Instant.now().getEpochSecond() - Storage.sessions.get(Chatter.of(user).getPlayer()).toInstant().getEpochSecond();
|
||||||
|
playtime /= 60d * 60d;
|
||||||
|
|
||||||
|
if (playtime > neededPlayTime) return Math.min(neededPlayTime, 100);
|
||||||
|
return (int) (playtime / (neededPlayTime / 100));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.velocitycore.advancements;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
|
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
||||||
|
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||||
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||||
|
import de.steamwar.linkage.Linked;
|
||||||
|
import de.steamwar.sql.SteamwarUser;
|
||||||
|
import de.steamwar.velocitycore.VelocityCore;
|
||||||
|
import de.steamwar.velocitycore.listeners.BasicListener;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Linked
|
||||||
|
public class AdvancementsManager extends BasicListener {
|
||||||
|
|
||||||
|
private static SelectAdvancementTabPacket selectAdvancementTabPacket;
|
||||||
|
|
||||||
|
static {
|
||||||
|
selectAdvancementTabPacket = new SelectAdvancementTabPacket(Optional.of("steamwar:advancements/root"));
|
||||||
|
|
||||||
|
try {
|
||||||
|
StateRegistry.PacketRegistry.ProtocolRegistry registry = StateRegistry.PLAY.getProtocolRegistry(ProtocolUtils.Direction.CLIENTBOUND, ProtocolVersion.MINECRAFT_1_21_6);
|
||||||
|
Field field = StateRegistry.PacketRegistry.ProtocolRegistry.class.getDeclaredField("packetClassToId");
|
||||||
|
field.setAccessible(true);
|
||||||
|
Object2IntMap<Class<? extends MinecraftPacket>> map = (Object2IntMap) field.get(registry);
|
||||||
|
map.put(SelectAdvancementTabPacket.class, 0x4E);
|
||||||
|
map.put(Advancement.Packet.class, 0x7B);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe(priority = -1000)
|
||||||
|
public void onPostLogin(PostLoginEvent event) {
|
||||||
|
((ConnectedPlayer) event.getPlayer()).getConnection().write(selectAdvancementTabPacket);
|
||||||
|
for (Advancement advancement : Advancements.getAll()) {
|
||||||
|
advancement.get(SteamwarUser.get(event.getPlayer().getUniqueId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onDisconnect(DisconnectEvent event) {
|
||||||
|
for (Advancement advancement : Advancements.getAll()) {
|
||||||
|
advancement.data.remove(SteamwarUser.get(event.getPlayer().getUniqueId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+55
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.velocitycore.advancements;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||||
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class SelectAdvancementTabPacket implements MinecraftPacket {
|
||||||
|
|
||||||
|
private Optional<String> identifier;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decode(ByteBuf byteBuf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
|
||||||
|
throw new UnsupportedOperationException("Packet is not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf byteBuf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
|
||||||
|
if (this.identifier.isPresent()) {
|
||||||
|
byteBuf.writeBoolean(true);
|
||||||
|
ProtocolUtils.writeString(byteBuf, this.identifier.get());
|
||||||
|
} else {
|
||||||
|
byteBuf.writeBoolean(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(MinecraftSessionHandler minecraftSessionHandler) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -35,6 +35,9 @@ import de.steamwar.sql.CheckedSchematic;
|
|||||||
import de.steamwar.sql.SchematicType;
|
import de.steamwar.sql.SchematicType;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.sql.UserPerm;
|
import de.steamwar.sql.UserPerm;
|
||||||
|
import de.steamwar.velocitycore.VelocityCore;
|
||||||
|
import de.steamwar.velocitycore.advancements.Advancement;
|
||||||
|
import de.steamwar.velocitycore.advancements.Advancements;
|
||||||
import de.steamwar.velocitycore.commands.*;
|
import de.steamwar.velocitycore.commands.*;
|
||||||
import de.steamwar.velocitycore.discord.DiscordBot;
|
import de.steamwar.velocitycore.discord.DiscordBot;
|
||||||
import de.steamwar.velocitycore.discord.util.DiscordRanks;
|
import de.steamwar.velocitycore.discord.util.DiscordRanks;
|
||||||
@@ -45,6 +48,7 @@ import net.kyori.adventure.text.event.ClickEvent;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
public class ConnectionListener extends BasicListener {
|
public class ConnectionListener extends BasicListener {
|
||||||
@@ -102,8 +106,12 @@ public class ConnectionListener extends BasicListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (newPlayers.contains(player.getUniqueId())) {
|
if (newPlayers.contains(player.getUniqueId())) {
|
||||||
|
Advancements.ROOT.get(user, (advancement, __) -> new Advancement.Data(advancement, user, 0));
|
||||||
Chatter.broadcast().system("JOIN_FIRST", player);
|
Chatter.broadcast().system("JOIN_FIRST", player);
|
||||||
newPlayers.remove(player.getUniqueId());
|
newPlayers.remove(player.getUniqueId());
|
||||||
|
VelocityCore.schedule(() -> {
|
||||||
|
Advancements.ROOT.get(user).update();
|
||||||
|
}).delay(1, TimeUnit.SECONDS).schedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!StreamingCommand.isNotStreaming(user)) {
|
if (!StreamingCommand.isNotStreaming(user)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user