From c374b5f5afe69c20bcd168a95fa7f12c482d0ca2 Mon Sep 17 00:00:00 2001
From: Tofaa <82680183+Tofaa2@users.noreply.github.com>
Date: Thu, 22 Feb 2024 01:08:31 +0400
Subject: [PATCH] concurrency

---
 .idea/gradle.xml                              |  1 +
 .idea/workspace.xml                           |  7 +++-
 .../entitylib/wrapper/WrapperEntity.java      | 40 ++++++++++++-------
 .../entitylib/wrapper/WrapperPlayer.java      | 36 +++++++++++++----
 .../testentitylib/TestEntityLibPlugin.java    | 27 ++++++++-----
 5 files changed, 77 insertions(+), 34 deletions(-)

diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 888bc59..228b351 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -13,6 +13,7 @@
             <option value="$PROJECT_DIR$/common" />
             <option value="$PROJECT_DIR$/platforms" />
             <option value="$PROJECT_DIR$/platforms/spigot" />
+            <option value="$PROJECT_DIR$/test-plugin" />
           </set>
         </option>
       </GradleProjectSettings>
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 91c8087..908c560 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,7 +4,11 @@
     <option name="autoReloadType" value="SELECTIVE" />
   </component>
   <component name="ChangeListManager">
-    <list default="true" id="9d5d9b6f-43c8-41a4-bb42-a66ffc96c9b0" name="Changes" comment="" />
+    <list default="true" id="9d5d9b6f-43c8-41a4-bb42-a66ffc96c9b0" name="Changes" comment="">
+      <change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPlayer.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPlayer.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java" beforeDir="false" afterPath="$PROJECT_DIR$/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java" afterDir="false" />
+    </list>
     <option name="SHOW_DIALOG" value="false" />
     <option name="HIGHLIGHT_CONFLICTS" value="true" />
     <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
@@ -303,6 +307,7 @@
       <workItem from="1708352150286" duration="3592000" />
       <workItem from="1708462795417" duration="1244000" />
       <workItem from="1708508458793" duration="103000" />
+      <workItem from="1708512937708" duration="3296000" />
     </task>
     <servers />
   </component>
diff --git a/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java
index 0df09bb..66da417 100644
--- a/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java
+++ b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java
@@ -15,6 +15,7 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
 
 public class WrapperEntity implements Tickable, TrackedEntity {
 
@@ -38,10 +39,11 @@ public class WrapperEntity implements Tickable, TrackedEntity {
         this.entityType = entityType;
         this.entityMeta = entityMeta;
         this.ticking = true;
-        this.viewers = new HashSet<>();
-        this.passengers = new HashSet<>();
+        this.viewers = ConcurrentHashMap.newKeySet();
+        this.passengers = ConcurrentHashMap.newKeySet();
     }
 
+
     public boolean spawn(Location location) {
         if (spawned) return false;
         this.location = location;
@@ -124,19 +126,27 @@ public class WrapperEntity implements Tickable, TrackedEntity {
         if (!viewers.add(uuid)) {
             return;
         }
-        WrapperPlayServerSpawnEntity packet = new WrapperPlayServerSpawnEntity(
-                entityId,
-                Optional.of(this.uuid),
-                entityType,
-                location.getPosition(),
-                location.getPitch(),
-                location.getYaw(),
-                location.getYaw(),
-                0,
-                Optional.empty()
-        );
-        sendPacket(uuid, packet);
-        sendPacket(uuid, entityMeta.createPacket());
+        if (location == null) {
+            if (EntityLib.getApi().getSettings().isDebugMode()) {
+                EntityLib.getPlatform().getLogger().warning("Location is null for entity " + entityId + ". Cannot spawn.");
+            }
+            return;
+        }
+        if (spawned) {
+            WrapperPlayServerSpawnEntity packet = new WrapperPlayServerSpawnEntity(
+                    entityId,
+                    Optional.of(this.uuid),
+                    entityType,
+                    location.getPosition(),
+                    location.getPitch(),
+                    location.getYaw(),
+                    location.getYaw(),
+                    0,
+                    Optional.empty()
+            );
+            sendPacket(uuid, packet);
+            sendPacket(uuid, entityMeta.createPacket());
+        }
     }
 
     public void addViewer(User user) {
diff --git a/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPlayer.java b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPlayer.java
index 7b35b3f..b78970e 100644
--- a/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPlayer.java
+++ b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPlayer.java
@@ -1,15 +1,16 @@
 package me.tofaa.entitylib.wrapper;
 
-import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
 import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
 import com.github.retrooper.packetevents.protocol.player.*;
+import com.github.retrooper.packetevents.protocol.world.Location;
 import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfo;
 import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoRemove;
 import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate;
-import me.tofaa.entitylib.EntityLib;
+import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnPlayer;
 import me.tofaa.entitylib.meta.EntityMeta;
 import net.kyori.adventure.text.Component;
 
+import java.util.ArrayList;
 import java.util.List;
 
 public class WrapperPlayer extends WrapperLivingEntity {
@@ -17,14 +18,13 @@ public class WrapperPlayer extends WrapperLivingEntity {
     private final UserProfile profile;
     private GameMode gameMode = GameMode.CREATIVE;
     private Component displayName;
-
+    private boolean tablist = true;
 
     public WrapperPlayer(UserProfile profile, int entityId) {
         super(entityId, profile.getUUID(), EntityTypes.PLAYER, EntityMeta.createMeta(entityId, EntityTypes.PLAYER));
         this.profile = profile;
     }
 
-
     public void setGameMode(GameMode gameMode) {
         this.gameMode = gameMode;
         sendPacketsToViewers(new WrapperPlayServerPlayerInfo(
@@ -57,14 +57,34 @@ public class WrapperPlayer extends WrapperLivingEntity {
 
     @Override
     public void addViewer(User user) {
+        //user.sendPacket(createAddPacket());
+        sendJoiningPackets();
         super.addViewer(user);
-        user.sendPacket(createAddPacket());
     }
 
     @Override
     public void removeViewer(User user) {
-        super.removeViewer(user);
         user.sendPacket(createRemovePacket());
+        super.removeViewer(user);
+    }
+
+    @Override
+    public boolean spawn(Location location) {
+        this.setLocation(location);
+        WrapperPlayServerSpawnPlayer packet = new WrapperPlayServerSpawnPlayer(getEntityId(), getUuid(), location, getEntityMeta());
+        sendPacketsToViewers(packet);
+        return true;
+        //return super.spawn(location);
+    }
+
+    private void sendJoiningPackets() {
+        List<WrapperPlayServerPlayerInfo.PlayerData> data = new ArrayList<>();
+        data.add(new WrapperPlayServerPlayerInfo.PlayerData(displayName, profile, gameMode, null, -1));
+        WrapperPlayServerPlayerInfo p1 = new WrapperPlayServerPlayerInfo(
+                WrapperPlayServerPlayerInfo.Action.ADD_PLAYER,
+                data
+        );
+        sendPacketsToViewers(p1);
     }
 
     private WrapperPlayServerPlayerInfoUpdate createAddPacket() {
@@ -72,7 +92,7 @@ public class WrapperPlayer extends WrapperLivingEntity {
                 WrapperPlayServerPlayerInfoUpdate.Action.ADD_PLAYER,
                 new WrapperPlayServerPlayerInfoUpdate.PlayerInfo(
                         profile,
-                        true, -1, gameMode, null, null
+                        true, -1, gameMode, displayName, null
                 )
         );
     }
@@ -81,4 +101,6 @@ public class WrapperPlayer extends WrapperLivingEntity {
         return new WrapperPlayServerPlayerInfoRemove(getUuid());
     }
 
+
+
 }
diff --git a/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java b/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java
index 40bbe86..ad65255 100644
--- a/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java
+++ b/test-plugin/src/main/java/me/tofaa/testentitylib/TestEntityLibPlugin.java
@@ -2,6 +2,7 @@ package me.tofaa.testentitylib;
 
 import com.github.retrooper.packetevents.PacketEvents;
 import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
+import com.github.retrooper.packetevents.protocol.player.UserProfile;
 import io.github.retrooper.packetevents.util.SpigotConversionUtil;
 import me.tofaa.entitylib.APIConfig;
 import me.tofaa.entitylib.EntityLib;
@@ -10,6 +11,7 @@ import me.tofaa.entitylib.spigot.SpigotEntityLibAPI;
 import me.tofaa.entitylib.spigot.SpigotEntityLibPlatform;
 import me.tofaa.entitylib.wrapper.WrapperEntity;
 import me.tofaa.entitylib.event.types.*;
+import me.tofaa.entitylib.wrapper.WrapperPlayer;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
@@ -17,11 +19,13 @@ import org.bukkit.entity.Player;
 import org.bukkit.plugin.java.JavaPlugin;
 import org.jetbrains.annotations.NotNull;
 
+import java.util.UUID;
+
 public class TestEntityLibPlugin extends JavaPlugin implements CommandExecutor {
 
 
     private SpigotEntityLibAPI api;
-    private WrapperEntity e;
+    private WrapperPlayer e;
 
     @Override
     public void onEnable() {
@@ -50,17 +54,18 @@ public class TestEntityLibPlugin extends JavaPlugin implements CommandExecutor {
     public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
         if (!(sender instanceof Player)) return false;
         Player player = (Player) sender;
-        if (e == null) {
-            e = api.spawnEntity(EntityTypes.CHICKEN, SpigotConversionUtil.fromBukkitLocation(player.getLocation()));
-            e.addViewer(player.getUniqueId());
-            player.sendMessage("Spawned");
+        if (e != null) {
+            e.remove();
+            player.sendMessage("Removed");
+            e = null;
+            return true;
         }
-        ChickenMeta meta = (ChickenMeta) e.getEntityMeta();
-        meta.setBaby(!meta.isBaby());
-        meta.setHasGlowingEffect(!meta.hasGlowingEffect());
-        meta.setHasNoGravity(!meta.hasNoGravity());
-
-        player.sendMessage("Updated");
+        UUID uuid = UUID.randomUUID();
+        UserProfile profile = new UserProfile(uuid, "RandomGoon");
+        e = new WrapperPlayer(profile, EntityLib.getPlatform().getEntityIdProvider().provide(uuid, EntityTypes.PLAYER));
+        e.addViewer(player.getUniqueId());
+        api.spawnEntity(e, SpigotConversionUtil.fromBukkitLocation(player.getLocation()));
+        player.sendMessage("Spawned");
         return true;
     }