This commit is contained in:
ef3d0c3e 2024-08-10 18:12:41 +02:00
parent 6cda65066b
commit f99d2a2039
22 changed files with 672 additions and 40 deletions

View file

@ -41,6 +41,12 @@
<version>1.21.1-R0.1-SNAPSHOT</version> <version>1.21.1-R0.1-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.21.1-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency> <dependency>
<groupId>com.comphenix.protocol</groupId> <groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId> <artifactId>ProtocolLib</artifactId>
@ -66,6 +72,11 @@
<artifactId>fastboard</artifactId> <artifactId>fastboard</artifactId>
<version>2.1.3</version> <version>2.1.3</version>
</dependency> </dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.17.0</version>
</dependency>
<dependency> <dependency>
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
<artifactId>guava</artifactId> <artifactId>guava</artifactId>

View file

@ -0,0 +1,35 @@
package org.ef3d0c3e.sheepwars.events;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.ef3d0c3e.sheepwars.player.CPlayer;
import org.ef3d0c3e.sheepwars.teams.Team;
import javax.annotation.Nullable;
@AllArgsConstructor
public class TeamChangeEvent extends Event
{
private static final HandlerList HANDLERS_LIST = new HandlerList();
public static HandlerList getHandlerList()
{
return HANDLERS_LIST;
}
@Override
public HandlerList getHandlers()
{
return HANDLERS_LIST;
}
@Getter
final private CPlayer player;
@Getter
final private @Nullable Team oldTeam;
@Getter
final private @Nullable Team newTeam;
}

View file

@ -9,6 +9,8 @@ import org.ef3d0c3e.sheepwars.level.LevelFactory;
import org.ef3d0c3e.sheepwars.level.lobby.LobbyLevel; import org.ef3d0c3e.sheepwars.level.lobby.LobbyLevel;
import org.ef3d0c3e.sheepwars.packets.PacketListenerFactory; import org.ef3d0c3e.sheepwars.packets.PacketListenerFactory;
import java.util.Random;
public class Game { public class Game {
private static void changePhase(WantsListen.Target phase) private static void changePhase(WantsListen.Target phase)
{ {
@ -28,6 +30,12 @@ public class Game {
//@Getter //@Getter
//private static GameLevel level; //private static GameLevel level;
private static final Random random = new Random();
public static int nextInt()
{
return random.nextInt();
}
/** /**
* Sets default phase to lobby * Sets default phase to lobby

View file

@ -0,0 +1,61 @@
package org.ef3d0c3e.sheepwars.hologram;
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import com.github.retrooper.packetevents.util.Vector3d;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity;
import lombok.NonNull;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import org.ef3d0c3e.sheepwars.packets.EntityMetadata;
import org.ef3d0c3e.sheepwars.packets.ItemProjectileMetadata;
import org.ef3d0c3e.sheepwars.player.CPlayer;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
/**
* Represent a text component
*/
public abstract class HologramItemComponent extends HologramComponent
{
protected HologramItemComponent(@NonNull Vector offset)
{
super(offset);
}
protected abstract @NonNull ItemStack getItem(final @NonNull CPlayer cp);
protected int getNetworkOffset() { return 1; }
protected @NonNull List<PacketWrapper<?>> build(final @NonNull Location location, final int networkId, final @NonNull CPlayer cp)
{
// Spawn
final Location loc = location.clone().add(getOffset());
final WrapperPlayServerSpawnEntity spawn = new WrapperPlayServerSpawnEntity(
networkId, Optional.of(UUID.randomUUID()),
EntityTypes.ITEM,
new Vector3d(loc.getX(), loc.getY(), loc.getZ()),
loc.getYaw(), 0.f, loc.getPitch(),
0,
Optional.empty()
);
// Metadata
final WrapperPlayServerEntityMetadata meta = new WrapperPlayServerEntityMetadata(
networkId,
Arrays.asList(
new EntityMetadata.NoGravity(true).into(),
new EntityMetadata.Silent(true).into(),
new ItemProjectileMetadata.Item(getItem(cp)).into()
)
);
return List.of(spawn, meta);
}
}

View file

@ -14,6 +14,7 @@ import lombok.NonNull;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import org.ef3d0c3e.sheepwars.packets.ArmorStandMetadata;
import org.ef3d0c3e.sheepwars.packets.EntityMetadata; import org.ef3d0c3e.sheepwars.packets.EntityMetadata;
import org.ef3d0c3e.sheepwars.player.CPlayer; import org.ef3d0c3e.sheepwars.player.CPlayer;
@ -54,7 +55,10 @@ public abstract class HologramTextComponent extends HologramComponent
.into(), .into(),
new EntityMetadata.NoGravity(true).into(), new EntityMetadata.NoGravity(true).into(),
new EntityMetadata.CustomNameVisible(true).into(), new EntityMetadata.CustomNameVisible(true).into(),
new EntityMetadata.CustomName(getText(cp)).into() new EntityMetadata.CustomName(getText(cp)).into(),
new ArmorStandMetadata.Status()
.isMarker(true)
.into()
) )
); );

View file

@ -15,11 +15,18 @@ import org.bukkit.event.entity.*;
import org.bukkit.event.entity.EntityDismountEvent; import org.bukkit.event.entity.EntityDismountEvent;
import org.bukkit.event.entity.EntityMountEvent; import org.bukkit.event.entity.EntityMountEvent;
import org.bukkit.event.inventory.CraftItemEvent; import org.bukkit.event.inventory.CraftItemEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.InventoryInteractEvent;
import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.PlayerInventory;
import org.ef3d0c3e.sheepwars.events.*; import org.ef3d0c3e.sheepwars.events.*;
import org.ef3d0c3e.sheepwars.game.Game; import org.ef3d0c3e.sheepwars.game.Game;
import org.ef3d0c3e.sheepwars.items.IItem;
import org.ef3d0c3e.sheepwars.player.skin.SkinItem;
import java.util.UUID; import java.util.UUID;
@ -33,10 +40,11 @@ public class LobbyEvents implements Listener
ev.getPlayer().getHandle().teleport(Game.getLobby().getSpawn()); ev.getPlayer().getHandle().teleport(Game.getLobby().getSpawn());
final PlayerInventory inv = ev.getPlayer().getHandle().getInventory(); final PlayerInventory inv = ev.getPlayer().getHandle().getInventory();
inv.clear();
//inv.setItem(0, TeamItem.getItem(ev.getPlayer())); //inv.setItem(0, TeamItem.getItem(ev.getPlayer()));
//inv.setItem(1, KitItem.getItem(ev.getPlayer())); //inv.setItem(1, KitItem.getItem(ev.getPlayer()));
//inv.setItem(4, RocketItem.getItem(ev.getPlayer())); inv.setItem(4, RocketItem.getItem(ev.getPlayer()));
//inv.setItem(7, SkinItem.getItem(ev.getPlayer())); inv.setItem(7, SkinItem.getItem(ev.getPlayer()));
} }
/* /*
@ -54,15 +62,15 @@ public class LobbyEvents implements Listener
final ItemStack replace = KitItem.getItem(ev.getPlayer()); final ItemStack replace = KitItem.getItem(ev.getPlayer());
if (!ItemBase.replace(ev.getPlayer().getHandle().getInventory(), KitItem.ITEM, replace)) if (!ItemBase.replace(ev.getPlayer().getHandle().getInventory(), KitItem.ITEM, replace))
ev.getPlayer().getHandle().getInventory().setItem(1, replace); ev.getPlayer().getHandle().getInventory().setItem(1, replace);
} }*/
@EventHandler @EventHandler
public void onSkinChange(final SkinChangeEvent ev) public void onSkinChange(final SkinChangeEvent ev)
{ {
final ItemStack replace = SkinItem.getItem(ev.getPlayer()); final ItemStack replace = SkinItem.getItem(ev.getPlayer());
if (!ItemBase.replace(ev.getPlayer().getHandle().getInventory(), SkinItem.ITEM, replace)) if (!IItem.replace(ev.getPlayer().getHandle().getInventory(), SkinItem.ITEM, replace))
ev.getPlayer().getHandle().getInventory().setItem(7, replace); ev.getPlayer().getHandle().getInventory().setItem(7, replace);
}*/ }
// Cancel all unwanted events // Cancel all unwanted events
@EventHandler @EventHandler
@ -74,6 +82,20 @@ public class LobbyEvents implements Listener
ev.setCancelled(true); ev.setCancelled(true);
} }
@EventHandler
public void onInventoryDrag(final InventoryDragEvent ev)
{
if (ev.getInventory().equals(ev.getWhoClicked().getInventory()))
ev.setCancelled(true);
}
@EventHandler
public void onInventoryClick(final InventoryClickEvent ev)
{
if (ev.getInventory().equals(ev.getWhoClicked().getInventory()))
ev.setCancelled(true);
}
@EventHandler @EventHandler
public void onFoodLevelChange(final FoodLevelChangeEvent ev) public void onFoodLevelChange(final FoodLevelChangeEvent ev)
{ {

View file

@ -0,0 +1,82 @@
package org.ef3d0c3e.sheepwars.level.lobby;
import lombok.NonNull;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.util.Vector;
import org.bukkit.inventory.ItemStack;
import org.ef3d0c3e.sheepwars.events.WantsListen;
import org.ef3d0c3e.sheepwars.hologram.Hologram;
import org.ef3d0c3e.sheepwars.hologram.HologramComponent;
import org.ef3d0c3e.sheepwars.hologram.HologramItemComponent;
import org.ef3d0c3e.sheepwars.hologram.HologramTextComponent;
import org.ef3d0c3e.sheepwars.player.CPlayer;
public class LobbyHologram extends Hologram {
private static final int NETWORK_ID = 0xFF877710;
private final Location location;
public LobbyHologram(final Location location)
{
super(NETWORK_ID);
this.location = location;
// Center item
addComponent(new HologramItemComponent(new Vector(0, 0, 0))
{
final ItemStack item = new ItemStack(Material.WHITE_WOOL);
@Override
protected @NonNull ItemStack getItem(@NonNull CPlayer cp)
{
return item;
}
});
// Left item
addComponent(new HologramItemComponent(new Vector(0.9, 0, 0))
{
final ItemStack item = new ItemStack(Material.IRON_SWORD);
@Override
protected @NonNull ItemStack getItem(@NonNull CPlayer cp)
{
return item;
}
});
// Right item
addComponent(new HologramItemComponent(new Vector(-0.9, 0, 0))
{
final ItemStack item = new ItemStack(Material.BOW);
@Override
protected @NonNull ItemStack getItem(@NonNull CPlayer cp)
{
return item;
}
});
// Title
addComponent(new HologramTextComponent(new Vector(0, 0.4, 0)) {
final static Component title = Component.text("SheepWars")
.color(TextColor.color(140, 187, 64))
.decorate(TextDecoration.BOLD);
@Override @NonNull
protected Component getText(@NonNull CPlayer cp) {
return title;
}
});
}
@Override
public @NonNull Location getLocation(@NonNull CPlayer cp) {
return location;
}
}

View file

@ -16,11 +16,13 @@ import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import org.bukkit.*; import org.bukkit.*;
import org.ef3d0c3e.sheepwars.SheepWars; import org.ef3d0c3e.sheepwars.SheepWars;
import org.ef3d0c3e.sheepwars.hologram.HologramFactory;
import org.ef3d0c3e.sheepwars.level.Level; import org.ef3d0c3e.sheepwars.level.Level;
import org.ef3d0c3e.sheepwars.level.VoidBiomeProvider; import org.ef3d0c3e.sheepwars.level.VoidBiomeProvider;
import org.ef3d0c3e.sheepwars.level.VoidChunkGenerator; import org.ef3d0c3e.sheepwars.level.VoidChunkGenerator;
import org.ef3d0c3e.sheepwars.npc.NPCFactory; import org.ef3d0c3e.sheepwars.npc.NPCFactory;
import org.ef3d0c3e.sheepwars.player.skin.SkinNPC; import org.ef3d0c3e.sheepwars.player.skin.SkinNPC;
import org.ef3d0c3e.sheepwars.teams.TeamNPC;
import java.io.*; import java.io.*;
@ -32,9 +34,9 @@ public class LobbyLevel extends Level
private Location spawn; private Location spawn;
//@Getter //@Getter
//private LobbyHologram hologram; private LobbyHologram hologram;
private SkinNPC skinNpc; private SkinNPC skinNpc;
//private TeamNPC teamNpc; private TeamNPC teamNpc;
//private KitNPC kitNpc; //private KitNPC kitNpc;
/** /**
@ -51,18 +53,16 @@ public class LobbyLevel extends Level
{ {
spawn = config.SPAWN.getLocation(getHandle()); spawn = config.SPAWN.getLocation(getHandle());
/*
hologram = new LobbyHologram(config.INFO.getLocation(getHandle())); hologram = new LobbyHologram(config.INFO.getLocation(getHandle()));
HologramFactory.register(hologram); HologramFactory.register(hologram);
*/
skinNpc = new SkinNPC(config.SKIN.getLocation(getHandle())); skinNpc = new SkinNPC(config.SKIN.getLocation(getHandle()));
NPCFactory.register(skinNpc); NPCFactory.register(skinNpc);
/*
teamNpc = new TeamNPC(config.TEAM.getLocation(getHandle())); teamNpc = new TeamNPC(config.TEAM.getLocation(getHandle()));
NPCFactory.register(teamNpc); NPCFactory.register(teamNpc);
/*
kitNpc = new KitNPC(config.KIT.getLocation(getHandle())); kitNpc = new KitNPC(config.KIT.getLocation(getHandle()));
NPCFactory.register(kitNpc); NPCFactory.register(kitNpc);
*/ */

View file

@ -0,0 +1,59 @@
package org.ef3d0c3e.sheepwars.level.lobby;
import lombok.NonNull;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.event.block.Action;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.util.Vector;
import org.ef3d0c3e.sheepwars.items.IItem;
import org.ef3d0c3e.sheepwars.items.ItemFactory;
import org.ef3d0c3e.sheepwars.player.CPlayer;
import java.text.MessageFormat;
public class RocketItem extends IItem
{
public RocketItem()
{
super();
}
@Override
protected boolean onInteract(final Player p, final ItemStack item, final Action action, final EquipmentSlot hand, final Block clicked, final BlockFace face)
{
if (p.getCooldown(item.getType()) != 0) return true;
p.getLocation().getWorld().playSound(p.getLocation(), Sound.ENTITY_FIREWORK_ROCKET_LAUNCH, 12.f, 1.f);
p.setVelocity(p.getVelocity()
.clone().add(new Vector(0.0, 0.8, 0.0)));
p.setCooldown(item.getType(), 30);
return true;
}
@Override
protected boolean onDrop(final Player p, final ItemStack item) { return true; }
static final public RocketItem ITEM = new RocketItem();
/**
* Gets item for player
* @param cp Player to get item for
* @return Item
*/
public static @NonNull ItemStack getItem(final CPlayer cp)
{
final ItemStack item = new ItemStack(Material.FIREWORK_ROCKET);
final ItemMeta meta = item.getItemMeta();
meta.setDisplayName(MessageFormat.format("§a{0} §7{1}", cp.getLocale().ITEMS_ROCKET, cp.getLocale().ITEMS_RIGHTCLICK));
item.setItemMeta(meta);
ItemFactory.registerItem(ITEM);
return ITEM.apply(item);
}
}

View file

@ -69,6 +69,8 @@ public class Locale
public String TEAM_PICKER; public String TEAM_PICKER;
public String TEAM_NPCNAME; public String TEAM_NPCNAME;
public String TEAM_NPCCURRENT; public String TEAM_NPCCURRENT;
public String TEAM_RED;
public String TEAM_BLUE;
// Kits // Kits
public String KIT_PICKER; public String KIT_PICKER;

View file

@ -4,7 +4,6 @@ import com.comphenix.protocol.wrappers.EnumWrappers;
import com.github.retrooper.packetevents.PacketEvents; import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.protocol.entity.data.EntityData; import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import com.github.retrooper.packetevents.protocol.npc.NPC;
import com.github.retrooper.packetevents.protocol.player.GameMode; import com.github.retrooper.packetevents.protocol.player.GameMode;
import com.github.retrooper.packetevents.protocol.player.TextureProperty; import com.github.retrooper.packetevents.protocol.player.TextureProperty;
import com.github.retrooper.packetevents.protocol.player.UserProfile; import com.github.retrooper.packetevents.protocol.player.UserProfile;
@ -15,8 +14,8 @@ import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.ef3d0c3e.sheepwars.packets.ArmorStandMetadata;
import org.ef3d0c3e.sheepwars.packets.EntityMetadata; import org.ef3d0c3e.sheepwars.packets.EntityMetadata;
import org.ef3d0c3e.sheepwars.packets.PlayerMetadata; import org.ef3d0c3e.sheepwars.packets.PlayerMetadata;
import org.ef3d0c3e.sheepwars.player.CPlayer; import org.ef3d0c3e.sheepwars.player.CPlayer;
@ -139,7 +138,7 @@ public abstract class PlayerNPC
final WrapperPlayServerSpawnEntity spawn = new WrapperPlayServerSpawnEntity( final WrapperPlayServerSpawnEntity spawn = new WrapperPlayServerSpawnEntity(
networkId+i+1, Optional.of(UUID.randomUUID()), networkId+i+1, Optional.of(UUID.randomUUID()),
EntityTypes.ARMOR_STAND, EntityTypes.ARMOR_STAND,
new Vector3d(loc.getX(), loc.getY()+(tags.size()-i-1)*0.3, loc.getZ()), new Vector3d(loc.getX(), loc.getY()+(tags.size()-i-1)*0.3+1.80, loc.getZ()),
0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
0, 0,
Optional.empty() Optional.empty()
@ -153,7 +152,10 @@ public abstract class PlayerNPC
.into(), .into(),
new EntityMetadata.NoGravity(true).into(), new EntityMetadata.NoGravity(true).into(),
new EntityMetadata.CustomNameVisible(true).into(), new EntityMetadata.CustomNameVisible(true).into(),
new EntityMetadata.CustomName(tag).into() new EntityMetadata.CustomName(tag).into(),
new ArmorStandMetadata.Status()
.isMarker(true)
.into()
) )
); );

View file

@ -28,18 +28,18 @@ public class ArmorStandMetadata {
} }
public Status hasArms(boolean v) { public Status hasArms(boolean v) {
value = (byte)(value | (v ? 0b10 : 0b0));
return this;
}
public Status hasBasePlate(boolean v) {
value = (byte)(value | (v ? 0b100 : 0b0)); value = (byte)(value | (v ? 0b100 : 0b0));
return this; return this;
} }
public Status isMarker(boolean v) { public Status hasBasePlate(boolean v) {
value = (byte)(value | (v ? 0b1000 : 0b0)); value = (byte)(value | (v ? 0b1000 : 0b0));
return this; return this;
} }
public Status isMarker(boolean v) {
value = (byte)(value | (v ? 0b10000 : 0b0));
return this;
}
} }
} }

View file

@ -0,0 +1,25 @@
package org.ef3d0c3e.sheepwars.packets;
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
import org.bukkit.inventory.ItemStack;
public class ItemProjectileMetadata {
public static class Item implements IntoEntityData {
@Override
public EntityData into() {
return new EntityData(
8,
EntityDataTypes.ITEMSTACK,
SpigotConversionUtil.fromBukkitItemStack(value)
);
}
ItemStack value;
public Item(final ItemStack value) {
this.value = value;
}
}
}

View file

@ -13,6 +13,7 @@ import org.ef3d0c3e.sheepwars.events.CPlayerJoinEvent;
import org.ef3d0c3e.sheepwars.events.CPlayerQuitEvent; import org.ef3d0c3e.sheepwars.events.CPlayerQuitEvent;
import org.ef3d0c3e.sheepwars.events.WantsListen; import org.ef3d0c3e.sheepwars.events.WantsListen;
import org.ef3d0c3e.sheepwars.locale.Locale; import org.ef3d0c3e.sheepwars.locale.Locale;
import org.ef3d0c3e.sheepwars.teams.Team;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.text.MessageFormat; import java.text.MessageFormat;
@ -95,17 +96,6 @@ public class CPlayer {
if (cp.isOnline()) f.operation(cp); if (cp.isOnline()) f.operation(cp);
} }
/**
* The player handle
*/
@Getter
private Player handle;
/**
* The OfflinePlayer handle
*/
@Getter
private OfflinePlayer offlinePlayer;
/** /**
* The locale configured for the player * The locale configured for the player
*/ */
@ -117,6 +107,17 @@ public class CPlayer {
@Getter @Getter
private CosmeticManager cosmetics = new CosmeticManager(this); private CosmeticManager cosmetics = new CosmeticManager(this);
/**
* The player handle
*/
@Getter
private Player handle;
/**
* The OfflinePlayer handle
*/
@Getter
private OfflinePlayer offlinePlayer;
/** /**
* Updates the player handle * Updates the player handle
* @param handle New handle * @param handle New handle
@ -143,6 +144,21 @@ public class CPlayer {
return offlinePlayer.isOnline(); return offlinePlayer.isOnline();
} }
/**
* The player's team
* May not be null in lobby phase, null in game phase means spectator i.e. joined after the game started
*/
@Getter
private Team team = null;
/**
* @note Don't call! Use {@link Team.setPlayerTeam(cp, team)}
* @param team New team
*/
public void setTeam(Team team) {
this.team = team;
}
/** /**
* Events for the player wrapper * Events for the player wrapper
* When a player joins or quits * When a player joins or quits

View file

@ -3,6 +3,7 @@ package org.ef3d0c3e.sheepwars.player;
import lombok.Getter; import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import lombok.Setter; import lombok.Setter;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
@ -61,10 +62,11 @@ public class CosmeticManager {
final CPlayer cp = CPlayer.get(ev.getPlayer()); final CPlayer cp = CPlayer.get(ev.getPlayer());
String message; String message;
//if (cp.getTeam() == null) if (cp.getTeam() == null)
message = MessageFormat.format("§f{0}§8:§7 {1}", cp.getHandle().getName(), ev.getMessage()); message = MessageFormat.format("§f{0}§8:§7 {1}", cp.getHandle().getName(), ev.getMessage());
//else else {
//message = MessageFormat.format("{0} | {1}§8:§7 {2}", cp.getTeam().getColoredName(), cp.getHandle().getName(), ev.getMessage()); message = MessageFormat.format("{0} | {1}§8:§7 {2}", cp.getTeam().getName(cp), cp.getHandle().getName(), ev.getMessage());
}
Bukkit.broadcastMessage(message); Bukkit.broadcastMessage(message);
} }

View file

@ -0,0 +1,58 @@
package org.ef3d0c3e.sheepwars.player.skin;
import lombok.NonNull;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.event.block.Action;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.ef3d0c3e.sheepwars.Util;
import org.ef3d0c3e.sheepwars.items.IItem;
import org.ef3d0c3e.sheepwars.items.ItemFactory;
import org.ef3d0c3e.sheepwars.player.CPlayer;
import java.text.MessageFormat;
public class SkinItem extends IItem
{
public SkinItem()
{
super();
}
@Override
protected boolean onInteract(final Player p, final ItemStack item, final Action action, final EquipmentSlot hand, final Block clicked, final BlockFace face)
{
p.openInventory(new SkinMenu(CPlayer.get(p)).getInventory());
return true;
}
@Override
protected boolean onDrop(final Player p, final ItemStack item) { return true; }
static final public SkinItem ITEM = new SkinItem();
/**
* Gets item for player
* @param cp Player to get item for
* @return Item
*/
public static @NonNull ItemStack getItem(final CPlayer cp)
{
final ItemStack item = (cp.getCosmetics().getCurrentSkin() == null)
? cp.getCosmetics().getOriginalSkin().getDisplayItem()
: cp.getCosmetics().getCurrentSkin().getDisplayItem();
final ItemMeta meta = item.getItemMeta();
if (cp.getCosmetics().getCurrentSkin() == null)
meta.setDisplayName(MessageFormat.format("§a{0} §7{1}", cp.getLocale().ITEMS_SKIN, cp.getLocale().ITEMS_RIGHTCLICK));
else
meta.setDisplayName(MessageFormat.format("§a{0} §8: §6{1} §7{2}", cp.getLocale().ITEMS_SKIN, cp.getCosmetics().getCurrentSkin().getName(), cp.getLocale().ITEMS_RIGHTCLICK));
meta.setLore(Util.coloredLore("§7", cp.getLocale().ITEMS_SKINLORE));
item.setItemMeta(meta);
ItemFactory.registerItem(ITEM);
return ITEM.apply(item);
}
}

View file

@ -0,0 +1,120 @@
package org.ef3d0c3e.sheepwars.teams;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
import jline.internal.Nullable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NonNull;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextColor;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.ef3d0c3e.sheepwars.events.CPlayerJoinEvent;
import org.ef3d0c3e.sheepwars.events.TeamChangeEvent;
import org.ef3d0c3e.sheepwars.events.WantsListen;
import org.ef3d0c3e.sheepwars.player.CPlayer;
import org.ef3d0c3e.sheepwars.game.Game;
import java.util.HashSet;
@AllArgsConstructor
public abstract class Team {
@Getter
private final ChatColor chatColor;
@Getter
private final TextColor color;
private HashSet<CPlayer> players;
private Team(final ChatColor chatColor, final TextColor color)
{
this.chatColor = chatColor;
this.color = color;
players = new HashSet<>();
}
public abstract String getName(final CPlayer cp);
public Component getColoredName(final CPlayer cp)
{
return Component.text(getName(cp))
.color(TextColor.color(color));
}
/**
* Executes lambda for each member of the team
* @param f Lambda to execute for each member
*/
public void forEachMember(final CPlayer.ForEachPlayer f)
{
for (final CPlayer cp : players)
f.operation(cp);
}
/**
* Executes lambda for each member of the team
* @param pre Player predicate
* @param f Lambda to execute for each member
*/
public void forEachMember(final CPlayer.PlayerPredicate pre, final CPlayer.ForEachPlayer f)
{
for (final CPlayer cp : players)
if (pre.operation(cp)) f.operation(cp);
}
public int count() {
return players.size();
}
/**
* Sets the player's team
* @param cp The player to change the team of
* @param team The new team
*/
public static void setPlayerTeam(final @NonNull CPlayer cp, final @Nullable Team team) {
final Team oldTeam = cp.getTeam();
if (oldTeam != null) oldTeam.players.remove(cp);
cp.setTeam(team);
if (team != null) team.players.add(cp);
if (team != oldTeam)
Bukkit.getPluginManager().callEvent(new TeamChangeEvent(cp, oldTeam, team));
}
public static Team RED = new Team(ChatColor.RED, TextColor.color(255, 0, 0)) {
@Override
public String getName(CPlayer cp) {
return cp.getLocale().TEAM_RED;
}
};
public static Team BLUE = new Team(ChatColor.BLUE, TextColor.color(0, 0, 255)) {
@Override
public String getName(CPlayer cp) {
return cp.getLocale().TEAM_BLUE;
}
};
@WantsListen(phase = WantsListen.Target.Lobby)
public static class Events implements Listener
{
@EventHandler
public void onJoin(final CPlayerJoinEvent ev)
{
if (RED.count() < BLUE.count())
{
Team.setPlayerTeam(ev.getPlayer(), RED);
}
else if (BLUE.count() < RED.count()) {
Team.setPlayerTeam(ev.getPlayer(), BLUE);
}
// Random team
else {
Team.setPlayerTeam(ev.getPlayer(), Game.nextInt() % 2 == 0 ? RED : BLUE);
}
}
}
}

View file

@ -0,0 +1,108 @@
package org.ef3d0c3e.sheepwars.teams;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.google.common.collect.Lists;
import com.mojang.authlib.properties.Property;
import lombok.NonNull;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.scheduler.BukkitRunnable;
import org.ef3d0c3e.sheepwars.SheepWars;
import org.ef3d0c3e.sheepwars.events.TeamChangeEvent;
import org.ef3d0c3e.sheepwars.events.WantsListen;
import org.ef3d0c3e.sheepwars.npc.NPCFactory;
import org.ef3d0c3e.sheepwars.npc.PlayerNPC;
import org.ef3d0c3e.sheepwars.player.CPlayer;
import java.util.List;
public class TeamNPC extends PlayerNPC {
private static final int NETWORK_ID = 0xFF777720;
private final Location location;
public TeamNPC(Location location) {
super(NETWORK_ID);
this.location = location;
}
@Override
protected @NonNull String getName() {
return "skin";
}
@Override
protected @NonNull List<Component> getNametag(@NonNull CPlayer cp) {
if (cp.getCosmetics().getCurrentSkin() == null)
return Lists.newArrayList(
Component.text(cp.getLocale().TEAM_NPCNAME)
.color(TextColor.color(207, 50, 200))
.decorate(TextDecoration.BOLD));
else
return Lists.newArrayList(
Component.text(cp.getLocale().TEAM_NPCNAME)
.color(TextColor.color(207, 50, 200))
.decorate(TextDecoration.BOLD),
Component.text(cp.getLocale().TEAM_NPCCURRENT)
.color(TextColor.color(85, 85, 127))
.decorate(TextDecoration.UNDERLINED),
Component.text(cp.getCosmetics().getCurrentSkin().getName())
.color(TextColor.color(180, 85, 120))
);
}
@Override
protected @NonNull Property getTextures(@NonNull CPlayer cp) {
return new Property("textures",
"ewogICJ0aW1lc3RhbXAiIDogMTcwMTk1OTQ2MjQ4NSwKICAicHJvZmlsZUlkIiA6ICJmODY0ZjY3ZGJlN2Y0OTBlYTZlODQzMjg2M2NkZWMxOCIsCiAgInByb2ZpbGVOYW1lIiA6ICJCb3lmcmllbmQ1MDY1IiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzIzMDgwZWZlMzdkNTk0ZjU0ZjNjMTgxYmRlNTBlMTI4ZWQyZjQyYmVkOGQzNjk3N2Y4ZTQwNmRmZDY0ZWZkZmQiCiAgICB9CiAgfQp9",
"hB0+1tCYxTvdjYlYS7wtwqbf30CNa/8BmkrpWv7mA0MFiQIikInm+rZEZbyHFFOba8Dc5Ee9hC/pu4rHwBqXN4XjsFELFqUHymKnhOSNmUfY7aA0rn+CaNrJOP7LSrajSN+r7qgRsXUph/7yEaTpMhWwu+nfzbxtaS7e8WqjqHtMYdjWg30HSTqrSYzmobo9wh3twbuEFil8dCTdG3A9YkICfhYeuAgwDENGe220ThPC4HJsyPS1NCAkuwfGHKFyjqomUkPm0o6ijnb4I5naSvGFFLqvjJDFQ2dwui8TacykoLj+Mou3NnSTawcutBD10HiMF/mgssZTsINim1Da4uOZR9FsShiAk5Z4nq7unh0vPdH+lgCoTaN5tD0DCmrZt5OLSEqpzx62EoYRWM5nUXRISVHKKADpra424O9zSytOCwjGGvYVg6uB6lOOb+Gm1+VDEU+7QzwhpYiMFaqiofZDJw7LNQ0EZcbbbTUFfUE7/d/X4sb2AGQno7RGVAdWrz/Kszf6/ri+Wru4GRHZBaS3LVnxXU4FUL7P9yF3ZPrpNZIt14f1WSWmk1ltGnwNwK8HfSRfo7uWZtDVZZWOeJA1bqTYMDP9n1hIHYgrLdIEmXpGK3RVytYeKbQVLWbTtPKTzPMhDaDyQkwGint0HgFm3jS29sRejdAMF81Hjt4=");
}
@Override
protected @NonNull Location getLocation(@NonNull CPlayer cp) {
return location;
}
@Override
protected boolean sendPredicate(@NonNull CPlayer cp) {
return cp.getHandle().getWorld() == location.getWorld();
}
@Override
protected void onInteract(@NonNull CPlayer cp, EnumWrappers.Hand hand, boolean sneaking) {
new BukkitRunnable() {
@Override
public void run() {
if (!cp.isOnline()) return;
if (cp.getTeam() == Team.RED) {
Team.setPlayerTeam(cp, Team.BLUE);
} else {
Team.setPlayerTeam(cp, Team.RED);
}
}
}.runTask(SheepWars.getPlugin());
}
@Override
protected void update(final @NonNull CPlayer cp) {
// Resend nametag
removeNametag(cp, 3);
sendNametag(cp);
// Resend skin
sendInfo(cp, true);
}
@WantsListen(phase = WantsListen.Target.Lobby)
public static class Events implements Listener {
@EventHandler
public void onTeamChange(final TeamChangeEvent ev) {
((TeamNPC) NPCFactory.get(NETWORK_ID)).update(ev.getPlayer());
}
}
}

View file

@ -1,7 +1,7 @@
offset: [0, 64, 0] offset: [0, 64, 0]
spawn: [0.5, 65, 0.5, 0, 0] spawn: [0.5, 65, 0.5, 0, 0]
limbo: 55 limbo: 55
info: [0.5, 59.5, 20.5, 0, 0] info: [0.5, 60.5, 20.5, 0, 0]
skin: [2.5, 58, 40.5, -179.9, 0] skin: [2.5, 58, 40.5, -179.9, 0]
team: [6.5, 58, 39.5, -179.9, 0] team: [6.5, 58, 39.5, -179.9, 0]
kit: [-1.5, 58, 40.5, -179.9, 0] kit: [-1.5, 58, 40.5, -179.9, 0]

View file

@ -55,7 +55,8 @@ team:
picker: "Choisissez une équipe" picker: "Choisissez une équipe"
npcname: "Choisissez une équipe" npcname: "Choisissez une équipe"
npccurrent: "Votre équipe:" npccurrent: "Votre équipe:"
red: "Rouge"
blue: "Bleue"
kit: kit:
picker: "Choisissez un kit" picker: "Choisissez un kit"
npcname: "Choisissez un kit" npcname: "Choisissez un kit"

View file

@ -40,6 +40,10 @@
<id>sonatype</id> <id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url> <url>https://oss.sonatype.org/content/groups/public/</url>
</repository> </repository>
<repository>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
</repositories> </repositories>
<dependencies> <dependencies>

View file

@ -1,7 +1,9 @@
package org.ef3d0c3e.sheepwars.v1_21_R0; package org.ef3d0c3e.sheepwars.v1_21_R0;
import com.github.retrooper.packetevents.PacketEvents; import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.protocol.chat.RemoteChatSession;
import com.github.retrooper.packetevents.protocol.player.GameMode; import com.github.retrooper.packetevents.protocol.player.GameMode;
import com.github.retrooper.packetevents.protocol.player.PublicProfileKey;
import com.github.retrooper.packetevents.protocol.player.TextureProperty; import com.github.retrooper.packetevents.protocol.player.TextureProperty;
import com.github.retrooper.packetevents.protocol.player.UserProfile; import com.github.retrooper.packetevents.protocol.player.UserProfile;
import com.github.retrooper.packetevents.protocol.world.Difficulty; import com.github.retrooper.packetevents.protocol.world.Difficulty;
@ -14,7 +16,9 @@ import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPl
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerRespawn; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerRespawn;
import com.mojang.authlib.properties.Property; import com.mojang.authlib.properties.Property;
import com.mojang.authlib.properties.PropertyMap; import com.mojang.authlib.properties.PropertyMap;
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
import lombok.NonNull; import lombok.NonNull;
import net.kyori.adventure.text.Component;
import net.minecraft.core.GlobalPos; import net.minecraft.core.GlobalPos;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
import net.minecraft.network.protocol.game.ClientboundRespawnPacket; import net.minecraft.network.protocol.game.ClientboundRespawnPacket;
@ -67,6 +71,9 @@ public class Skin implements SkinVersionWrapper
cp.getHandle().getUniqueId() cp.getHandle().getUniqueId()
); );
final ServerPlayer p = ((CraftPlayer)cp.getHandle()).getHandle();
final net.minecraft.network.chat.RemoteChatSession chatSession = p.getChatSession();
// Add info packet // Add info packet
final WrapperPlayServerPlayerInfoUpdate info = new WrapperPlayServerPlayerInfoUpdate( final WrapperPlayServerPlayerInfoUpdate info = new WrapperPlayServerPlayerInfoUpdate(
WrapperPlayServerPlayerInfoUpdate.Action.ADD_PLAYER, WrapperPlayServerPlayerInfoUpdate.Action.ADD_PLAYER,
@ -85,14 +92,19 @@ public class Skin implements SkinVersionWrapper
true, true,
cp.getHandle().getPing(), cp.getHandle().getPing(),
GameMode.getById(cp.getHandle().getGameMode().getValue()), GameMode.getById(cp.getHandle().getGameMode().getValue()),
null, Component.text(cp.getHandle().getName()),
null // FIXME: This is not correct as the player chat session is still invalid
new RemoteChatSession(chatSession.sessionId(), new PublicProfileKey(
chatSession.profilePublicKey().data().expiresAt(),
chatSession.profilePublicKey().data().key(),
chatSession.profilePublicKey().data().keySignature()
)
)
) )
); );
// Respawn packet // Respawn packet
final ServerLevel level = ((CraftWorld)loc.getWorld()).getHandle(); final ServerLevel level = ((CraftWorld)loc.getWorld()).getHandle();
final ServerPlayer p = ((CraftPlayer)cp.getHandle()).getHandle();
final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn( final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(
new Dimension(level.getLevel().dimensionType().hashCode()), new Dimension(level.getLevel().dimensionType().hashCode()),