Compare commits

..

21 Commits

Author SHA1 Message Date
M2ke4U
365639d7db Updated maven repo link 2024-10-01 21:42:25 +08:00
M2ke4U
5257a5ccc9 [ci skip]Added option to publish dev-bundle 2024-08-12 18:32:24 +08:00
M2ke4U
a1fffec02a [ci skip]Added molia maven repo 2024-08-12 18:31:13 +08:00
ShintoKosei
79a21ab81a [ci skip] Upload SVG 2024-02-06 17:24:47 +08:00
ShintoKosei
d577729ca2 [ci skip] Update README 2024-02-06 14:35:30 +08:00
ShintoKosei
b41225df65 [ci skip] change logo_5 in ver/1.20.2 2024-02-06 14:23:52 +08:00
ShintoKosei
3a473302d0 [ci skip] Update readme.md & Upload new logo in ver/1.20.2 2024-02-06 14:20:36 +08:00
Klop233
a1df619285 [ci skip] Added Chinese readme 2024-02-06 10:08:48 +08:00
M2ke4U
a4ba907b33 [ci skip]Added logo in README 2024-02-05 21:44:52 +08:00
M2ke4U
aa5acdd1b5 [ci skip]Added logo file 2024-02-05 21:39:55 +08:00
M2ke4U
f9b62e717e [ci skip]Added bstats 2024-02-05 09:19:39 +08:00
MrHua269
7d04bb5038 Do not check tickThread while removing bots 2024-02-02 01:14:57 +00:00
MrHua269
0e70acaa9c Fix java compile in AbstractMinecart 2024-02-01 13:54:52 +00:00
MrHua269
0872f03352 Fix java compile in ServerBot 2024-02-01 10:47:20 +00:00
MrHua269
f5550b8cc1 Fixes in folia and fakeplayer 2024-02-01 09:55:19 +00:00
MrHua269
909b208b67 Merge remote-tracking branch 'origin/ver/1.20.2' into ver/1.20.2 2024-01-31 09:29:52 +00:00
MrHua269
b159640ebe Fixes in fakeplayer and io_uring channel type 2024-01-31 09:29:36 +00:00
M2ke4U
76aa79aa3c Correct wrong thread name
How careless I could be()
2024-01-30 21:14:57 +08:00
MrHua269
f2d8696e94 Io_uring channel type support 2024-01-30 13:09:21 +00:00
MrHua269
31e86623e1 Set CI auto release from release to prerelease 2024-01-30 13:09:10 +00:00
MrHua269
a290a8d6a0 Reapply leaves fakeplayer 2024-01-30 09:08:54 +00:00
20 changed files with 723 additions and 357 deletions

View File

@@ -60,4 +60,4 @@ jobs:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
file: "build/libs/luminol-1.20.2-paperclip.jar"
file_glob: true
prerelease: false
prerelease: true

View File

@@ -1,12 +1,17 @@
<img src="./public/image/Luminol_5.png" alt="Logo" align="right" width="250">
# Luminol
<h4>Luminol is a folia fork with many useful optimizations, configurable vanilla features, and more API supports, and it was designed for survival and anarchy servers</h4>
**English** | [中文](./README_CN.md)
[![MIT License](https://img.shields.io/github/license/LuminolMC/Luminol?style=flat-square)](LICENSE)
[![Issues](https://img.shields.io/github/issues/LuminolMC/Luminol?style=flat-square)](https://github.com/LuminolMC/Luminol/issues)
![Commit Activity](https://img.shields.io/github/commit-activity/w/LuminolMC/Luminol?style=flat-square)
![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/LuminolMC/Luminol?style=flat-square)
![GitHub all releases](https://img.shields.io/github/downloads/LuminolMC/Luminol/total?style=flat-square)
<h4>Luminol is a folia fork with many useful optimizations, configurable vanilla features, and more API supports, and it was designed for survival and anarchy servers</h4>
## Features
- Configurable vanilla features
- Tpsbar support
@@ -37,3 +42,6 @@ For maven
<version>1.20.2-R0.1-SNAPSHOT</version>
</dependency>
```
## BStats
![bStats](https://bstats.org/signatures/server-implementation/Luminol.svg "bStats")

48
README_CN.md Normal file
View File

@@ -0,0 +1,48 @@
<img src="./public/image/Luminol_5.png" alt="Logo" align="right" width="250">
# Luminol
<h4>Luminol 是一个基于folia的分支具有许多有用的优化、可配置的原版特性和更多的API支持它专为生存和无政府服务器设计</h4>
[English](./README.md) | **中文**
[![MIT License](https://img.shields.io/github/license/LuminolMC/Luminol?style=flat-square)](LICENSE)
[![Issues](https://img.shields.io/github/issues/LuminolMC/Luminol?style=flat-square)](https://github.com/LuminolMC/Luminol/issues)
![Commit Activity](https://img.shields.io/github/commit-activity/w/LuminolMC/Luminol?style=flat-square)
![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/LuminolMC/Luminol?style=flat-square)
![GitHub all releases](https://img.shields.io/github/downloads/LuminolMC/Luminol/total?style=flat-square)
## 特性
- 可配置的原版特性
- Tpsbar 支持
- 线性区域文件格式 (from kaiiju)
- 对单线程区域性能的优化
- 更多的插件开发API支持进行中
## 下载
任何版本都可以在 [release](https://github.com/LuminolMC/Luminol/releases), 中找到,您也可以通过以下步骤自己构建。
## 构建
要构建一个paperclip jar你需要运行以下命令。你可以在build/libs中找到jar注意需要JDK17
```shell
./gradlew applyPatches && ./gradlew createReobfPaperclipJar
```
## 使用API
使用 Gradle:
```kotlin
dependencies {
compileOnly("me.earthme.luminol:luminol-api:1.20.2-R0.1-SNAPSHOT")
}
```
使用 Maven
```xml
<dependency>
<groupId>me.earthme.luminol</groupId>
<artifactId>luminol-api</artifactId>
<version>1.20.2-R0.1-SNAPSHOT</version>
</dependency>
```
## BStats
![bStats](https://bstats.org/signatures/server-implementation/Luminol.svg "bStats")

View File

@@ -93,3 +93,41 @@ paperweight {
}
}
}
allprojects {
publishing {
repositories {
maven {
name = "githubPackage"
url = uri("https://maven.pkg.github.com/LuminolMC/Luminol")
credentials.username = System.getenv("GITHUB_USERNAME")
credentials.password = System.getenv("GITHUB_TOKEN")
}
maven {
name = "moliaMavenRepo"
url = uri("https://maven.nostal.ink/repository/maven-snapshots/")
credentials.username = System.getenv("MAVEN_REPO_USER")
credentials.password = System.getenv("MAVEN_REPO_PASSWORD")
}
publications {
register<MavenPublication>("gpr") {
from(components["java"])
}
}
}
}
}
publishing {
if (project.hasProperty("publishDevBundle")) {
publications.create<MavenPublication>("devBundle") {
artifact(tasks.generateDevelopmentBundle) {
artifactId = "dev-bundle"
}
}
}
}

View File

@@ -1,11 +1,11 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Mon, 29 Jan 2024 12:44:10 +0000
Date: Tue, 30 Jan 2024 09:03:08 +0000
Subject: [PATCH] Leaves fakeplayer API
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index b7e1c8bd8dd38e1a9e74925740b22dad61a75f49..36863cd765277b9b551ae04a4ecbee502c4d0a4e 100644
index b7e1c8bd8dd38e1a9e74925740b22dad61a75f49..5ee1ba3847599ac67b5cd8ca26e61b1231c45dcd 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -58,6 +58,7 @@ import org.jetbrains.annotations.Contract;
@@ -16,7 +16,7 @@ index b7e1c8bd8dd38e1a9e74925740b22dad61a75f49..36863cd765277b9b551ae04a4ecbee50
/**
* Represents the Bukkit core, for version and Server singleton handling
@@ -2836,6 +2837,18 @@ public final class Bukkit {
@@ -2836,6 +2837,17 @@ public final class Bukkit {
}
// Folia end - region threading API
@@ -30,13 +30,12 @@ index b7e1c8bd8dd38e1a9e74925740b22dad61a75f49..36863cd765277b9b551ae04a4ecbee50
+ return server.getBotManager();
+ }
+ // Leaves end - Bot API
+
+
@NotNull
public static Server.Spigot spigot() {
return server.spigot();
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index 85b169c04f44431363d4e14d4857140f160ceace..ed89520a9bf17a6f2665a17ded0c334d8f9bf130 100644
index 85b169c04f44431363d4e14d4857140f160ceace..9e12552aca127892d122a2616d303d3cdfc67416 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -58,6 +58,7 @@ import org.bukkit.util.CachedServerIcon;
@@ -52,6 +51,7 @@ index 85b169c04f44431363d4e14d4857140f160ceace..ed89520a9bf17a6f2665a17ded0c334d
public boolean isGlobalTickThread();
// Folia end - region threading API
+
+
+ // Leaves start - Bot API
+ /**
+ * Returns a bot manager.
@@ -60,14 +60,13 @@ index 85b169c04f44431363d4e14d4857140f160ceace..ed89520a9bf17a6f2665a17ded0c334d
+ */
+ @NotNull BotManager getBotManager();
+ // Leaves end - Bot API
+
}
diff --git a/src/main/java/top/leavesmc/leaves/entity/Bot.java b/src/main/java/top/leavesmc/leaves/entity/Bot.java
new file mode 100644
index 0000000000000000000000000000000000000000..02815077dcd6d5c1b155ef3ca5cd6e3a9c45c0b5
index 0000000000000000000000000000000000000000..8816683c795f9be6a4f112203cfac3f59d8faba5
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/entity/Bot.java
@@ -0,0 +1,51 @@
@@ -0,0 +1,46 @@
+package top.leavesmc.leaves.entity;
+
+import org.bukkit.entity.Player;
@@ -75,8 +74,6 @@ index 0000000000000000000000000000000000000000..02815077dcd6d5c1b155ef3ca5cd6e3a
+import org.jetbrains.annotations.Nullable;
+import top.leavesmc.leaves.entity.botaction.LeavesBotAction;
+
+import java.util.UUID;
+
+/**
+ * Represents a fakeplayer
+ */
@@ -98,15 +95,12 @@ index 0000000000000000000000000000000000000000..02815077dcd6d5c1b155ef3ca5cd6e3a
+ @NotNull
+ public String getRealName();
+
+ @Nullable
+ public UUID getCreatePlayerUUID();
+
+ /**
+ * Sets the fakeplayer action with args.
+ *
+ * @param action action name
+ * @param player player who create this action
+ * @param args passed action arguments
+ * @param args passed action arguments
+ */
+ public boolean setBotAction(@NotNull String action, @NotNull Player player, @NotNull String[] args);
+
@@ -115,7 +109,7 @@ index 0000000000000000000000000000000000000000..02815077dcd6d5c1b155ef3ca5cd6e3a
+ *
+ * @param action leaves bot action
+ * @param player player who create this action
+ * @param args passed action arguments
+ * @param args passed action arguments
+ */
+ public boolean setBotAction(@NotNull LeavesBotAction action, @NotNull Player player, @NotNull String[] args);
+}
@@ -477,58 +471,6 @@ index 0000000000000000000000000000000000000000..4a4fe07ce965d4a97e0d8105a91310da
+ return bot;
+ }
+}
diff --git a/src/main/java/top/leavesmc/leaves/event/bot/BotInventoryOpenEvent.java b/src/main/java/top/leavesmc/leaves/event/bot/BotInventoryOpenEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..e889f7e98ec9cb6a3b95d8ea865e25fffea662a1
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/event/bot/BotInventoryOpenEvent.java
@@ -0,0 +1,46 @@
+package top.leavesmc.leaves.event.bot;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import top.leavesmc.leaves.entity.Bot;
+
+public class BotInventoryOpenEvent extends BotEvent implements Cancellable {
+ private static final HandlerList handlers = new HandlerList();
+
+ private final Player player;
+ private boolean cancel = false;
+
+ public BotInventoryOpenEvent(@NotNull Bot who, @Nullable Player player) {
+ super(who);
+ this.player = player;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return cancel;
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ this.cancel = cancel;
+ }
+
+ @Nullable
+ public Player getOpenPlayer() {
+ return player;
+ }
+
+
+ @Override
+ public @NotNull HandlerList getHandlers() {
+ return handlers;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}
diff --git a/src/main/java/top/leavesmc/leaves/event/bot/BotJoinEvent.java b/src/main/java/top/leavesmc/leaves/event/bot/BotJoinEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..10afa5c7fd4ee8a4e72d64f8ca9bf8731ec2ad61

View File

@@ -1,11 +1,24 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Mon, 29 Jan 2024 13:22:53 +0000
Date: Tue, 30 Jan 2024 08:59:03 +0000
Subject: [PATCH] Leaves fakeplayer support
diff --git a/src/main/java/io/papermc/paper/threadedregions/RegionShutdownThread.java b/src/main/java/io/papermc/paper/threadedregions/RegionShutdownThread.java
index 2b48833023771fa965f131890ade98e9da3f5976..75c16116f684d434c1aa554d8ed13a638751772a 100644
--- a/src/main/java/io/papermc/paper/threadedregions/RegionShutdownThread.java
+++ b/src/main/java/io/papermc/paper/threadedregions/RegionShutdownThread.java
@@ -124,6 +124,8 @@ public final class RegionShutdownThread extends TickThread {
@Override
public final void run() {
+ top.leavesmc.leaves.bot.ServerBot.saveOrRemoveAllBot(); // Leaves - save or remove bot
+
// await scheduler termination
LOGGER.info("Awaiting scheduler termination for 60s");
if (TickRegions.getScheduler().halt(true, TimeUnit.SECONDS.toNanos(60L))) {
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index e531453e3d25700e38ff41548c7e32e278a6304d..f924a238f211c22a00b8df67a209dcfea751039c 100644
index e531453e3d25700e38ff41548c7e32e278a6304d..610642b0a0c3f17c66ec27ed812b97c68cee1be6 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -78,7 +78,17 @@ public class LuminolConfig {
@@ -39,7 +52,7 @@ index e531453e3d25700e38ff41548c7e32e278a6304d..f924a238f211c22a00b8df67a209dcfe
+ fakeplayerSkipSleep = get("gameplay.fakeplayer.fakeplayer_skip_sleep",fakeplayerSkipSleep);
+ fakeplayerResident = get("gameplay.fakeplayer.resident",fakeplayerResident);
+ fakeplayerSpawnPhantom = get("gameplay.fakeplayer.spawn_phantom_for_fakeplayer",fakeplayerSpawnPhantom);
+ fakeplayerRegenAmount = get("gameplay.fakeplayer.regen_amount",fakeplayerRegenAmount);
+ fakeplayerRegenAmount = Double.parseDouble(get("gameplay.fakeplayer.regen_amount",String.valueOf(fakeplayerRegenAmount)));
+ unableFakeplayerNames = get("gameplay.fakeplayer.name_black_list",unableFakeplayerNames);
+
+ if (fakeplayerSupport){
@@ -59,18 +72,6 @@ index e531453e3d25700e38ff41548c7e32e278a6304d..f924a238f211c22a00b8df67a209dcfe
}
public static <T> T get(String key,T def){
diff --git a/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java b/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java
index f0367a9cce13ef576fbb7023c0aba6eb48963606..7b156d147c409ded1b0385583e0b34d3bd5c48de 100644
--- a/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java
+++ b/src/main/java/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java
@@ -51,6 +51,7 @@ public abstract class SimpleCriterionTrigger<T extends SimpleCriterionTrigger.Si
}
protected void trigger(ServerPlayer player, Predicate<T> predicate) {
+ if (player instanceof top.leavesmc.leaves.bot.ServerBot) return; // Leaves - bot skip
PlayerAdvancements playerAdvancements = player.getAdvancements();
Set<CriterionTrigger.Listener<T>> set = (Set) playerAdvancements.criterionData.get(this); // Paper - fix AdvancementDataPlayer leak
if (set != null && !set.isEmpty()) {
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
index b84e9d5ae5efe1a8257a5f1f78a0ab66113a698e..832f6851a3f72cefe95c96757645374ac592f33b 100644
--- a/src/main/java/net/minecraft/network/Connection.java
@@ -91,10 +92,18 @@ index b84e9d5ae5efe1a8257a5f1f78a0ab66113a698e..832f6851a3f72cefe95c96757645374a
if (this.packetListener != null) {
throw new IllegalStateException("Listener already set");
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 675bbf1f69011f7f95fabc050c9877d6e70070b2..926b80aa09b0a593f4074efc86601ac176692c72 100644
index 675bbf1f69011f7f95fabc050c9877d6e70070b2..87d8338900d09be1962965abfd62f7484fa31a25 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -669,6 +669,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -128,6 +128,7 @@ import net.minecraft.util.profiling.metrics.storage.MetricsPersister;
import net.minecraft.util.thread.ReentrantBlockableEventLoop;
import net.minecraft.world.Difficulty;
import net.minecraft.world.RandomSequences;
+import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.ai.village.VillageSiege;
import net.minecraft.world.entity.npc.CatSpawner;
@@ -669,6 +670,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
// Paper end
@@ -103,7 +112,7 @@ index 675bbf1f69011f7f95fabc050c9877d6e70070b2..926b80aa09b0a593f4074efc86601ac1
this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD);
this.server.getPluginManager().callEvent(new ServerLoadEvent(ServerLoadEvent.LoadType.STARTUP));
this.connection.acceptConnections();
@@ -962,6 +964,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -962,6 +965,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Folia end - region threading
public void stopServer() {
@@ -128,7 +137,7 @@ index e38e2e5a7ddba9c140f362021b6be0b0974f7cd1..870a9c94885c983cd7a557b76cb4dbac
AdvancementProgress advancementprogress = this.getOrStartProgress(advancement);
boolean flag1 = advancementprogress.isDone();
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 3cba356b74362c2fc010d0c1bfb6eeecb449908e..45873f2c51a82287c5ab9bfec4d893bea39b42a5 100644
index 3cba356b74362c2fc010d0c1bfb6eeecb449908e..afcf83aea7e1b43cb925856076d6c09aa9e47800 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -1438,6 +1438,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -137,7 +146,7 @@ index 3cba356b74362c2fc010d0c1bfb6eeecb449908e..45873f2c51a82287c5ab9bfec4d893be
this.serverEntity.removePairing(player);
+ // Leaves start - render bot
+ if (entity instanceof top.leavesmc.leaves.bot.ServerBot bot) {
+ if (bot.alwaysSendData) {
+ if (me.earthme.luminol.LuminolConfig.alwaysSendFakeplayerData) {
+ bot.sendFakeData(player.connection, false);
+ }
+ }
@@ -146,10 +155,18 @@ index 3cba356b74362c2fc010d0c1bfb6eeecb449908e..45873f2c51a82287c5ab9bfec4d893be
}
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 755294e3f5b3fbcfbdc0cc85627b2487663ce591..5910c1585385d44e90280032ca3cc8e2ee2b4b70 100644
index 755294e3f5b3fbcfbdc0cc85627b2487663ce591..ea409d2a03c35990c6857c24305346a6ec7f4bf8 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -183,6 +183,7 @@ import org.bukkit.event.player.PlayerTeleportEvent;
@@ -98,7 +98,6 @@ import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.util.Unit;
import net.minecraft.world.damagesource.DamageSource;
-import net.minecraft.world.damagesource.DamageSources;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
@@ -183,6 +182,7 @@ import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import org.bukkit.inventory.MainHand;
@@ -157,11 +174,10 @@ index 755294e3f5b3fbcfbdc0cc85627b2487663ce591..5910c1585385d44e90280032ca3cc8e2
// CraftBukkit end
public class ServerPlayer extends Player {
@@ -826,21 +827,25 @@ public class ServerPlayer extends Player {
--this.invulnerableTime;
@@ -827,20 +827,24 @@ public class ServerPlayer extends Player {
}
- // Paper start - Configurable container update tick rate
// Paper start - Configurable container update tick rate
- if (--containerUpdateDelay <= 0) {
- this.containerMenu.broadcastChanges();
- containerUpdateDelay = this.level().paperConfig().tickRates.containerUpdate;
@@ -172,7 +188,6 @@ index 755294e3f5b3fbcfbdc0cc85627b2487663ce591..5910c1585385d44e90280032ca3cc8e2
- this.containerMenu = this.inventoryMenu;
+ // Leaves start - skip bot
+ if (!(this instanceof ServerBot)) {
+ // Paper start - Configurable container update tick rate
+ if (--containerUpdateDelay <= 0) {
+ this.containerMenu.broadcastChanges();
+ containerUpdateDelay = this.level().paperConfig().tickRates.containerUpdate;
@@ -193,7 +208,7 @@ index 755294e3f5b3fbcfbdc0cc85627b2487663ce591..5910c1585385d44e90280032ca3cc8e2
if (this.levitationStartPos != null) {
CriteriaTriggers.LEVITATION.trigger(this, this.levitationStartPos, this.tickCount - this.levitationStartTime);
}
@@ -1065,7 +1070,7 @@ public class ServerPlayer extends Player {
@@ -1065,7 +1069,7 @@ public class ServerPlayer extends Player {
java.util.List<org.bukkit.inventory.ItemStack> loot = new java.util.ArrayList<org.bukkit.inventory.ItemStack>(this.getInventory().getContainerSize());
boolean keepInventory = this.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || this.isSpectator();
@@ -202,7 +217,7 @@ index 755294e3f5b3fbcfbdc0cc85627b2487663ce591..5910c1585385d44e90280032ca3cc8e2
for (ItemStack item : this.getInventory().getContents()) {
if (!item.isEmpty() && !EnchantmentHelper.hasVanishingCurse(item)) {
loot.add(CraftItemStack.asCraftMirror(item));
@@ -1730,6 +1735,13 @@ public class ServerPlayer extends Player {
@@ -1730,6 +1734,13 @@ public class ServerPlayer extends Player {
this.lastSentHealth = -1.0F;
this.lastSentFood = -1;
@@ -236,19 +251,18 @@ index c4652f250e22f33e8505183b4050e08aedf9245c..18745ee33843d668613fd9e7f15d6a79
player.connection = this;
player.getTextFilter().join();
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 3f366ad035ada0ac8170d2925bbfe86b80bd84cb..f2329d24a4e3f4637b78d4894b0e6c99a0e00faa 100644
index 3f366ad035ada0ac8170d2925bbfe86b80bd84cb..c90fc6a926e19c74358bda6c6f3fa11dafba97bc 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -123,6 +123,8 @@ import org.bukkit.event.player.PlayerRespawnEvent.RespawnReason;
import org.bukkit.event.player.PlayerSpawnChangeEvent;
// CraftBukkit end
@@ -102,6 +102,7 @@ import net.minecraft.world.scores.Objective;
import net.minecraft.world.scores.PlayerTeam;
import net.minecraft.world.scores.Scoreboard; // Paper
import net.minecraft.world.scores.Team;
+import top.leavesmc.leaves.bot.ServerBot;
+
public abstract class PlayerList {
import org.slf4j.Logger;
public static final File USERBANLIST_FILE = new File("banned-players.json");
@@ -437,6 +439,21 @@ public abstract class PlayerList {
// CraftBukkit start
@@ -437,6 +438,21 @@ public abstract class PlayerList {
top.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerJoin(player); // Leaves - protocol
@@ -270,13 +284,13 @@ index 3f366ad035ada0ac8170d2925bbfe86b80bd84cb..f2329d24a4e3f4637b78d4894b0e6c99
final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage();
if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure
@@ -1092,6 +1109,13 @@ public abstract class PlayerList {
@@ -1092,6 +1108,13 @@ public abstract class PlayerList {
}
// Paper end
+ // Leaves start - bot support
+ if (me.earthme.luminol.LuminolConfig.fakeplayerSupport) {
+ ServerBot.getBots().forEach(bot1 ->
+ top.leavesmc.leaves.bot.ServerBot.getBots().forEach(bot1 ->
+ bot1.sendFakeDataIfNeed(entityplayer1, true)); // Leaves - render bot
+ }
+ // Leaves end - bot support
@@ -284,12 +298,12 @@ index 3f366ad035ada0ac8170d2925bbfe86b80bd84cb..f2329d24a4e3f4637b78d4894b0e6c99
// CraftBukkit end
return entityplayer1;
}
@@ -1201,12 +1225,17 @@ public abstract class PlayerList {
@@ -1201,12 +1224,17 @@ public abstract class PlayerList {
public String[] getPlayerNamesArray() {
List<ServerPlayer> players = new java.util.ArrayList<>(this.players); // Folia start - region threading
- String[] astring = new String[players.size()];
+ String[] astring = new String[players.size() + ServerBot.getBots().size()];
+ String[] astring = new String[players.size() + ServerBot.getBots().size()]; // Leaves - fakeplayer support
for (int i = 0; i < players.size(); ++i) {
astring[i] = ((ServerPlayer) players.get(i)).getGameProfile().getName();
@@ -303,12 +317,11 @@ index 3f366ad035ada0ac8170d2925bbfe86b80bd84cb..f2329d24a4e3f4637b78d4894b0e6c99
return astring;
}
@@ -1715,4 +1744,17 @@ public abstract class PlayerList {
@@ -1715,4 +1743,16 @@ public abstract class PlayerList {
public boolean isAllowCheatsForAllPlayers() {
return this.allowCheatsForAllPlayers;
}
+
+
+ // Leaves start - fakeplayer support
+ public void addNewBot(ServerBot bot) {
+ playersByName.put(bot.getScoreboardName().toLowerCase(java.util.Locale.ROOT), bot);
@@ -385,7 +398,7 @@ index f664da5a8413bb13cc95d2cf1604f11a5d285dae..2d5f6a69e0c2dc96375ec24d41522ae4
FeatureFlagSet featureflagset = player.level().enabledFeatures();
diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
index a127b6cbaab211d324d42b3bddcd6ebd84c250e3..2649177134985505a341c40473dfdbb210d0ae87 100644
index a127b6cbaab211d324d42b3bddcd6ebd84c250e3..6898de0b40e00125ba3153cacfc60a98493c8d38 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
@@ -70,6 +70,11 @@ public class PhantomSpawner implements CustomSpawner {
@@ -393,15 +406,15 @@ index a127b6cbaab211d324d42b3bddcd6ebd84c250e3..2649177134985505a341c40473dfdbb2
int j = Mth.clamp(serverstatisticmanager.getValue(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE);
boolean flag2 = true;
+ // Leaves start - fakeplayer spawn
+ if (entityplayer instanceof top.leavesmc.leaves.bot.ServerBot bot && bot.spawnPhantom) {
+ j = bot.notSleepTicks;
+ if (me.earthme.luminol.LuminolConfig.fakeplayerSpawnPhantom && entityplayer instanceof top.leavesmc.leaves.bot.ServerBot) {
+ j = world.paperConfig().entities.behavior.playerInsomniaStartTicks + 1;
+ }
+ // Leaves end - fakeplayer spawn
if (randomsource.nextInt(j) >= world.paperConfig().entities.behavior.playerInsomniaStartTicks) { // Paper
BlockPos blockposition1 = blockposition.above(20 + randomsource.nextInt(15)).east(-10 + randomsource.nextInt(21)).south(-10 + randomsource.nextInt(21));
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index ee66241a422acb8920395fd5e41578a966746f5c..913ea63d7103d6a54990b55683d4cf0341d4b722 100644
index ee66241a422acb8920395fd5e41578a966746f5c..a73fc518d5b6c156bf31a1d08d0a0fd0b31bd271 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -264,6 +264,7 @@ import org.yaml.snakeyaml.constructor.SafeConstructor;
@@ -420,13 +433,12 @@ index ee66241a422acb8920395fd5e41578a966746f5c..913ea63d7103d6a54990b55683d4cf03
// Paper start - Folia region threading API
private final io.papermc.paper.threadedregions.scheduler.FoliaRegionScheduler regionizedScheduler = new io.papermc.paper.threadedregions.scheduler.FoliaRegionScheduler(); // Folia - region threading
@@ -3241,4 +3243,12 @@ public final class CraftServer implements Server {
@@ -3241,4 +3243,11 @@ public final class CraftServer implements Server {
}
// Paper end
+
+
+ //Leaves start - Bot API
+ // Leaves start - Bot API
+ @Override
+ public CraftBotManager getBotManager() {
+ return botManager;
@@ -462,10 +474,10 @@ index 9f070a9f0894d88688ff50efc3f4dba8188c3885..5699adccb5c2e5e7e6612940cf42fcf9
// Water Animals
diff --git a/src/main/java/top/leavesmc/leaves/bot/BotCommand.java b/src/main/java/top/leavesmc/leaves/bot/BotCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..4563284facbfd01733d6a0efdfe7d0cabebdc1e7
index 0000000000000000000000000000000000000000..9aa304d4709149ce1104d05bb375d3cf7f54729e
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/bot/BotCommand.java
@@ -0,0 +1,330 @@
@@ -0,0 +1,274 @@
+package top.leavesmc.leaves.bot;
+
+import org.bukkit.Bukkit;
@@ -513,14 +525,13 @@ index 0000000000000000000000000000000000000000..4563284facbfd01733d6a0efdfe7d0ca
+ list.add("create");
+ list.add("remove");
+ list.add("action");
+ list.add("config");
+ list.add("list");
+ }
+
+ if (args.length == 2) {
+ switch (args[0]) {
+ case "create" -> list.add("<BotName>");
+ case "remove", "action", "config" ->
+ case "remove", "action" ->
+ list.addAll(ServerBot.getBots().stream().map(e -> e.getName().getString()).toList());
+ case "list" -> list.addAll(Bukkit.getWorlds().stream().map(WorldInfo::getName).toList());
+ }
@@ -533,16 +544,6 @@ index 0000000000000000000000000000000000000000..4563284facbfd01733d6a0efdfe7d0ca
+ list.addAll(Actions.getNames());
+ }
+ case "create" -> list.add("<BotSkinName>");
+ case "config" -> list.addAll(acceptConfig);
+ }
+ }
+
+ if (args.length == 4) {
+ switch (args[0]) {
+ case "config" -> {
+ list.add("true");
+ list.add("false");
+ }
+ }
+ }
+
@@ -552,13 +553,12 @@ index 0000000000000000000000000000000000000000..4563284facbfd01733d6a0efdfe7d0ca
+ list.addAll(action.getArgument().tabComplete(args.length - 4));
+ }
+ }
+
+ return list;
+ }
+
+ @Override
+ public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, String[] args) {
+ if (!testPermission(sender) || !me.earthme.luminol.LuminolConfig.fakeplayerSupport) return true;
+ if (!testPermission(sender)) return true;
+
+ if (args.length == 0) {
+ sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
@@ -572,8 +572,6 @@ index 0000000000000000000000000000000000000000..4563284facbfd01733d6a0efdfe7d0ca
+
+ case "action" -> this.onAction(sender, args);
+
+ case "config" -> this.onConfig(sender, args);
+
+ case "list" -> this.onList(sender, args);
+
+ default -> {
@@ -593,7 +591,7 @@ index 0000000000000000000000000000000000000000..4563284facbfd01733d6a0efdfe7d0ca
+
+ if (canCreate(sender, args[1])) {
+ if (sender instanceof Player player) {
+ new ServerBot.BotCreateState(player.getLocation(), args[1], args.length < 3 ? args[1] : args[2]).createAsync(bot -> bot.createPlayer = player.getUniqueId());
+ new ServerBot.BotCreateState(player.getLocation(), args[1], args.length < 3 ? args[1] : args[2]).createAsync(null);
+ } else if (sender instanceof ConsoleCommandSender) {
+ if (args.length < 6) {
+ sender.sendMessage(ChatColor.RED + "Use /bot create <name> <skin_name> <bukkit_world_name> <x> <y> <z> to create a fakeplayer");
@@ -709,48 +707,6 @@ index 0000000000000000000000000000000000000000..4563284facbfd01733d6a0efdfe7d0ca
+ sender.sendMessage("Action " + action.getName() + " has been issued to " + bot.getName().getString());
+ }
+
+ private static final List<String> acceptConfig = List.of("skip_sleep", "spawn_phantom", "always_send_data");
+
+ private void onConfig(CommandSender sender, String @NotNull [] args) {
+ if (args.length < 3) {
+ sender.sendMessage(ChatColor.RED + "Use /bot config <name> <config> to modify fakeplayer's config");
+ return;
+ }
+
+ ServerBot bot = ServerBot.getBot(args[1]);
+ if (bot == null) {
+ sender.sendMessage(ChatColor.RED + "This fakeplayer is not in server");
+ return;
+ }
+
+ if (!acceptConfig.contains(args[2])) {
+ sender.sendMessage(ChatColor.RED + "This config is not accept");
+ return;
+ }
+
+ if (args.length < 4) {
+ switch (args[2]) {
+ case "skip_sleep" -> sender.sendMessage(bot.getScoreboardName() + "'s skip_sleep: " + bot.fauxSleeping);
+ case "spawn_phantom" -> {
+ sender.sendMessage(bot.getScoreboardName() + "'s spawn_phantom: " + bot.spawnPhantom);
+ if (bot.spawnPhantom) {
+ sender.sendMessage(bot.getScoreboardName() + "'s not_sleeping_ticks: " + bot.notSleepTicks);
+ }
+ }
+ case "always_send_data" ->
+ sender.sendMessage(bot.getScoreboardName() + "'s always_send_data: " + bot.alwaysSendData);
+ }
+ } else {
+ boolean value = args[3].equals("true");
+ switch (args[2]) {
+ case "skip_sleep" -> bot.fauxSleeping = value;
+ case "spawn_phantom" -> bot.spawnPhantom = value;
+ case "always_send_data" -> bot.alwaysSendData = value;
+ }
+ sender.sendMessage(bot.getScoreboardName() + "'s " + args[2] + " changed: " + value);
+ }
+ }
+
+ private void onList(CommandSender sender, String @NotNull [] args) {
+ if (args.length < 2) {
+ Map<World, List<String>> botMap = new HashMap<>();
@@ -1028,10 +984,10 @@ index 0000000000000000000000000000000000000000..c3f114fba0759221b5fea0ccc4862f05
+}
diff --git a/src/main/java/top/leavesmc/leaves/bot/BotUtil.java b/src/main/java/top/leavesmc/leaves/bot/BotUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..8e8edd0a9fb53449fa3d1bee81629d667d0aa572
index 0000000000000000000000000000000000000000..be3a40e3100ec838cf8de6437cc6b1b0c454bc68
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/bot/BotUtil.java
@@ -0,0 +1,183 @@
@@ -0,0 +1,182 @@
+package top.leavesmc.leaves.bot;
+
+import com.google.common.base.Charsets;
@@ -1041,7 +997,6 @@ index 0000000000000000000000000000000000000000..8e8edd0a9fb53449fa3d1bee81629d66
+import net.minecraft.core.NonNullList;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.nbt.ListTag;
+import net.minecraft.nbt.NbtAccounter;
+import net.minecraft.nbt.NbtIo;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.world.entity.EquipmentSlot;
@@ -1264,10 +1219,10 @@ index 0000000000000000000000000000000000000000..daaece30b2a3983f1cc9ee9a851e8f37
+}
diff --git a/src/main/java/top/leavesmc/leaves/bot/ServerBot.java b/src/main/java/top/leavesmc/leaves/bot/ServerBot.java
new file mode 100644
index 0000000000000000000000000000000000000000..30391d5dc0e1bdaeaf9ee190e74c3da0440eeef8
index 0000000000000000000000000000000000000000..e9101aeae36b919659b865d1cdb800c16ff29180
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/bot/ServerBot.java
@@ -0,0 +1,760 @@
@@ -0,0 +1,735 @@
+package top.leavesmc.leaves.bot;
+
+import com.google.common.collect.Lists;
@@ -1277,8 +1232,6 @@ index 0000000000000000000000000000000000000000..30391d5dc0e1bdaeaf9ee190e74c3da0
+import com.mojang.authlib.GameProfile;
+import com.mojang.authlib.properties.Property;
+import io.papermc.paper.threadedregions.RegionizedServer;
+import io.papermc.paper.threadedregions.ThreadedRegionizer;
+import io.papermc.paper.threadedregions.TickRegionScheduler;
+import io.papermc.paper.util.TickThread;
+import net.minecraft.Util;
+import net.minecraft.core.BlockPos;
@@ -1322,17 +1275,19 @@ index 0000000000000000000000000000000000000000..30391d5dc0e1bdaeaf9ee190e74c3da0
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.craftbukkit.CraftWorld;
+import org.bukkit.craftbukkit.entity.CraftPlayer;
+import org.bukkit.craftbukkit.scheduler.CraftScheduler;
+import org.bukkit.craftbukkit.scheduler.MinecraftInternalPlugin;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.bukkit.plugin.Plugin;
+import org.bukkit.util.Vector;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import me.earthme.luminol.LuminolConfig;
+import top.leavesmc.leaves.bot.agent.BotAction;
+import top.leavesmc.leaves.bot.agent.actions.StopAction;
+import top.leavesmc.leaves.entity.Bot;
+import top.leavesmc.leaves.entity.CraftBot;
+import top.leavesmc.leaves.event.bot.BotCreateEvent;
+import top.leavesmc.leaves.event.bot.BotInventoryOpenEvent;
+import top.leavesmc.leaves.event.bot.BotJoinEvent;
+import top.leavesmc.leaves.util.MathUtils;
+
@@ -1353,7 +1308,6 @@ index 0000000000000000000000000000000000000000..30391d5dc0e1bdaeaf9ee190e74c3da0
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+// TODO remake all
+public class ServerBot extends ServerPlayer {
@@ -1369,17 +1323,12 @@ index 0000000000000000000000000000000000000000..30391d5dc0e1bdaeaf9ee190e74c3da0
+ public boolean waterSwim;
+ private Vec3 knockback;
+ public BotCreateState createState;
+ public UUID createPlayer;
+
+ private final ServerStatsCounter stats;
+ private final BotInventoryContainer container;
+
+ private static final List<ServerBot> bots = new CopyOnWriteArrayList<>();
+
+ public boolean spawnPhantom;
+ public int notSleepTicks;
+ public boolean alwaysSendData;
+
+ private ServerBot(MinecraftServer server, ServerLevel world, GameProfile profile) {
+ super(server, world, profile, ClientInformation.createDefault());
+ this.entityData.set(new EntityDataAccessor<>(16, EntityDataSerializers.INT), 0xFF);
@@ -1392,14 +1341,10 @@ index 0000000000000000000000000000000000000000..30391d5dc0e1bdaeaf9ee190e74c3da0
+ this.removeOnDeath = true;
+ this.stats = new BotStatsCounter(server);
+ this.container = new BotInventoryContainer(this);
+ this.fauxSleeping = me.earthme.luminol.LuminolConfig.fakeplayerSkipSleep;
+ this.waterSwim = true;
+ this.knockback = Vec3.ZERO;
+ this.tracingRange = world.spigotConfig.playerTrackingRange * world.spigotConfig.playerTrackingRange;
+ this.notSleepTicks = 0;
+
+ this.fauxSleeping = LuminolConfig.fakeplayerSkipSleep;
+ this.spawnPhantom = LuminolConfig.fakeplayerSpawnPhantom;
+ this.alwaysSendData = LuminolConfig.alwaysSendFakeplayerData;
+ }
+
+ public static ServerBot createBot(@NotNull BotCreateState state) {
@@ -1409,70 +1354,45 @@ index 0000000000000000000000000000000000000000..30391d5dc0e1bdaeaf9ee190e74c3da0
+
+ MinecraftServer server = MinecraftServer.getServer();
+
+ Supplier<ServerBot> creator = () -> {
+ BotCreateEvent event = new BotCreateEvent(state.name, state.skinName, state.loc, ChatColor.YELLOW + state.name + " joined the game");
+ server.server.getPluginManager().callEvent(event);
+ BotCreateEvent event = new BotCreateEvent(state.name, state.skinName, state.loc, ChatColor.YELLOW + state.name + " joined the game");
+ server.server.getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {
+ return null;
+ }
+
+ Location location = event.getCreateLocation();
+
+ ServerLevel world = ((CraftWorld) location.getWorld()).getHandle();
+ CustomGameProfile profile = new CustomGameProfile(BotUtil.getBotUUID(state), state.name, state.skin);
+
+ ServerBot bot = new ServerBot(server, world, profile);
+
+ bot.connection = new ServerGamePacketListenerImpl(server, new Connection(PacketFlow.SERVERBOUND) { // ?
+ @Override
+ public void send(@NotNull Packet<?> packet) {
+ }
+
+ @Override
+ public void send(@NotNull Packet<?> packet, @Nullable PacketSendListener packetsendlistener) {
+ }
+
+ @Override
+ public void send(@NotNull Packet<?> packet, @Nullable PacketSendListener callbacks, boolean flush) {
+ }
+ }, bot, CommonListenerCookie.createInitial(profile));
+ bot.isRealPlayer = true;
+ bot.createState = state;
+
+ if (event.getJoinMessage() != null) {
+ Bukkit.broadcastMessage(event.getJoinMessage());
+ }
+
+ bot.teleportTo(location.getX(), location.getY(), location.getZ());
+ bot.setRot(location.getYaw(), location.getPitch());
+ bot.getBukkitEntity().setRotation(location.getYaw(), location.getPitch());
+ world.addFreshEntity(bot, CreatureSpawnEvent.SpawnReason.COMMAND);
+
+ bot.renderAll();
+ server.getPlayerList().addNewBot(bot);
+ bots.add(bot);
+
+ BotJoinEvent event1 = new BotJoinEvent(bot.getBukkitPlayer());
+ server.server.getPluginManager().callEvent(event1);
+
+ return bot;
+ };
+
+ if (TickThread.isTickThreadFor(((CraftWorld) state.loc.getWorld()).getHandle(),state.loc.getBlockX() >> 4,state.loc.getBlockZ() >> 4)){
+ return creator.get();
+ if (event.isCancelled()) {
+ return null;
+ }
+
+ return CompletableFuture.supplyAsync(
+ creator,
+ task ->
+ RegionizedServer.getInstance().taskQueue.queueTickTaskQueue(
+ ((CraftWorld) state.loc.getWorld()).getHandle(),
+ state.loc.getBlockX() >> 4,
+ state.loc.getBlockZ() >> 4,
+ task
+ )
+ ).join();
+ Location location = event.getCreateLocation();
+
+ ServerLevel world = ((CraftWorld) location.getWorld()).getHandle();
+ CustomGameProfile profile = new CustomGameProfile(BotUtil.getBotUUID(state), state.name, state.skin);
+
+ ServerBot bot = new ServerBot(server, world, profile);
+
+ bot.connection = new ServerGamePacketListenerImpl(server, new Connection(PacketFlow.SERVERBOUND) {
+ @Override
+ public void send(@NotNull Packet<?> packet, @Nullable PacketSendListener packetsendlistener) {
+ }
+ }, bot, CommonListenerCookie.createInitial(profile));
+ bot.isRealPlayer = true;
+ bot.createState = state;
+
+ if (event.getJoinMessage() != null) {
+ Bukkit.broadcastMessage(event.getJoinMessage());
+ }
+
+ bot.teleportTo(location.getX(), location.getY(), location.getZ());
+ bot.setRot(location.getYaw(), location.getPitch());
+ bot.getBukkitEntity().setRotation(location.getYaw(), location.getPitch());
+ world.addFreshEntity(bot, CreatureSpawnEvent.SpawnReason.COMMAND);
+
+ bot.renderAll();
+ server.getPlayerList().addNewBot(bot);
+ bots.add(bot);
+
+ BotJoinEvent event1 = new BotJoinEvent(bot.getBukkitPlayer());
+ server.server.getPluginManager().callEvent(event1);
+
+ return bot;
+ }
+
+ public static boolean isCreateLegal(@NotNull String name) {
@@ -1505,7 +1425,7 @@ index 0000000000000000000000000000000000000000..30391d5dc0e1bdaeaf9ee190e74c3da0
+ }
+
+ public boolean needSendFakeData(ServerPlayer player) {
+ return alwaysSendData && (player.level() == this.level() && player.position().distanceToSqr(this.position()) > this.tracingRange);
+ return me.earthme.luminol.LuminolConfig.alwaysSendFakeplayerData && (player.level() == this.level() && player.position().distanceToSqr(this.position()) > this.tracingRange);
+ }
+
+ public void sendFakeDataIfNeed(ServerPlayer player, boolean login) {
@@ -1515,11 +1435,11 @@ index 0000000000000000000000000000000000000000..30391d5dc0e1bdaeaf9ee190e74c3da0
+ }
+
+ public void sendFakeData(ServerPlayerConnection playerConnection, boolean login) {
+ playerConnection.send(new ClientboundAddEntityPacket(this));
+ playerConnection.send(new ClientboundAddEntityPacket(this));
+ if (login) {
+ Bukkit.getScheduler().runTaskLater(CraftScheduler.MINECRAFT, () -> {
+ playerConnection.getPlayer().getBukkitEntity().taskScheduler.schedule(task -> {
+ connection.send(new ClientboundRotateHeadPacket(this, (byte) ((getYRot() * 256f) / 360f)));
+ }, 10);
+ },null,10);
+ } else {
+ connection.send(new ClientboundRotateHeadPacket(this, (byte) ((getYRot() * 256f) / 360f)));
+ }
@@ -1600,10 +1520,6 @@ index 0000000000000000000000000000000000000000..30391d5dc0e1bdaeaf9ee190e74c3da0
+ return;
+ }
+
+ if (spawnPhantom) {
+ notSleepTicks++;
+ }
+
+ if (fireTicks > 0) {
+ --fireTicks;
+ }
@@ -1620,21 +1536,19 @@ index 0000000000000000000000000000000000000000..30391d5dc0e1bdaeaf9ee190e74c3da0
+ this.updateLocation();
+ this.updatePlayerPose();
+
+ if (TickRegionScheduler.getCurrentRegion().getData().getCurrentTick() % 20 == 0) {
+ float health = getHealth();
+ float maxHealth = getMaxHealth();
+ float regenAmount = (float) (me.earthme.luminol.LuminolConfig.fakeplayerRegenAmount * 20);
+ float amount;
+ float health = getHealth();
+ float maxHealth = getMaxHealth();
+ float regenAmount = 0.010f;
+ float amount;
+
+ if (health < maxHealth - regenAmount) {
+ amount = health + regenAmount;
+ } else {
+ amount = maxHealth;
+ }
+
+ this.setHealth(amount);
+ if (health < maxHealth - regenAmount) {
+ amount = health + regenAmount;
+ } else {
+ amount = maxHealth;
+ }
+
+ this.setHealth(amount);
+
+ BlockPos blockposition = this.getOnPosLegacy();
+ BlockState iblockdata = this.level().getBlockState(blockposition);
+ Vec3 vec3d1 = this.collide(velocity);
@@ -1851,13 +1765,9 @@ index 0000000000000000000000000000000000000000..30391d5dc0e1bdaeaf9ee190e74c3da0
+ @Override
+ public @NotNull InteractionResult interact(@NotNull Player player, @NotNull InteractionHand hand) {
+ if (me.earthme.luminol.LuminolConfig.openFakeplayerInventory) {
+ if (player instanceof ServerPlayer player1 && player.getMainHandItem().isEmpty()) {
+ BotInventoryOpenEvent event = new BotInventoryOpenEvent(this.getBukkitEntity(), player1.getBukkitEntity());
+ server.server.getPluginManager().callEvent(event);
+ if (!event.isCancelled()) {
+ player.openMenu(new SimpleMenuProvider((i, inventory, p) -> ChestMenu.sixRows(i, inventory, container), getDisplayName()));
+ return InteractionResult.SUCCESS;
+ }
+ if (player.getMainHandItem().isEmpty()) {
+ player.openMenu(new SimpleMenuProvider((i, inventory, p) -> ChestMenu.sixRows(i, inventory, container), getDisplayName()));
+ return InteractionResult.SUCCESS;
+ }
+ }
+ return super.interact(player, hand);
@@ -1938,11 +1848,29 @@ index 0000000000000000000000000000000000000000..30391d5dc0e1bdaeaf9ee190e74c3da0
+ }
+
+ public static boolean removeAllBot() {
+ Iterator<ServerBot> iterator = bots.iterator();
+ while (iterator.hasNext()) {
+ ServerBot bot = iterator.next();
+ bot.die(bot.damageSources().fellOutOfWorld());
+ }
+ CompletableFuture.allOf(
+ bots.stream()
+ .map(bot ->{
+ //Do not check if it is on region thread,return to the target region anyway
+ /*if (TickThread.isTickThreadFor(bot)){
+ bot.die(bot.damageSources().fellOutOfWorld());
+ return CompletableFuture.completedFuture(null);
+ }*/
+
+ return CompletableFuture.runAsync(()->{
+ bot.die(bot.damageSources().fellOutOfWorld());
+ }, task ->
+ RegionizedServer.getInstance().taskQueue.queueTickTaskQueue(
+ bot.serverLevel(),
+ bot.sectionX,
+ bot.sectionZ,
+ task
+ )
+ );
+ })
+ .toArray(CompletableFuture[]::new)
+ ).join();
+ bots.clear();
+ return true;
+ }
+
@@ -1994,19 +1922,21 @@ index 0000000000000000000000000000000000000000..30391d5dc0e1bdaeaf9ee190e74c3da0
+
+ public void createAsync(Consumer<ServerBot> consumer) {
+ Bukkit.getAsyncScheduler().runNow(CraftScheduler.MINECRAFT,scheduledTask -> {
+ try {
+ if (skinName != null) {
+ this.skin = MojangAPI.getSkin(skinName);
+ }
+
+
+ ServerBot bot = createBot(this);
+ if (bot != null && consumer != null) {
+ consumer.accept(bot);
+ }
+ }catch (Exception e){
+ MinecraftServer.LOGGER.error("Exception in processing async task for fakeplayer!",e);
+ if (skinName != null) {
+ this.skin = MojangAPI.getSkin(skinName);
+ }
+
+ RegionizedServer.getInstance().taskQueue.queueTickTaskQueue(
+ ((CraftWorld) loc.getWorld()).getHandle(),
+ loc.getBlockX() >> 4,
+ loc.getBlockZ() >> 4,
+ ()->{
+ ServerBot bot = createBot(this);
+ if (bot != null && consumer != null) {
+ consumer.accept(bot);
+ }
+ }
+ );
+ });
+ }
+
@@ -2873,23 +2803,17 @@ index 0000000000000000000000000000000000000000..345932e779f5187355ca722c2bb9b05f
+}
diff --git a/src/main/java/top/leavesmc/leaves/bot/agent/actions/UseItemOnAction.java b/src/main/java/top/leavesmc/leaves/bot/agent/actions/UseItemOnAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..f4837f60909763df89ea7474f70dd0236360e657
index 0000000000000000000000000000000000000000..886e37227e66dc25653b8ad53fef600c705aa101
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/bot/agent/actions/UseItemOnAction.java
@@ -0,0 +1,56 @@
@@ -0,0 +1,40 @@
+package top.leavesmc.leaves.bot.agent.actions;
+
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.InteractionHand;
+import net.minecraft.world.level.ClipContext;
+import net.minecraft.world.level.block.Blocks;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.world.level.block.entity.TrappedChestBlockEntity;
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.phys.BlockHitResult;
+import net.minecraft.world.phys.HitResult;
+import org.bukkit.Bukkit;
+import org.bukkit.craftbukkit.scheduler.CraftScheduler;
+import org.jetbrains.annotations.NotNull;
+import top.leavesmc.leaves.bot.ServerBot;
+import top.leavesmc.leaves.bot.agent.BotAction;
@@ -2915,43 +2839,27 @@ index 0000000000000000000000000000000000000000..f4837f60909763df89ea7474f70dd023
+ @Override
+ public boolean doTick(@NotNull ServerBot bot) {
+ HitResult result = bot.getRayTrace(5, ClipContext.Fluid.NONE);
+ if (result instanceof BlockHitResult blockHitResult) {
+ BlockState state = bot.serverLevel().getBlockState(blockHitResult.getBlockPos());
+ if (result.getType() == HitResult.Type.BLOCK) {
+ bot.punch();
+ if (state.getBlock() == Blocks.TRAPPED_CHEST) {
+ BlockEntity entity = bot.serverLevel().getBlockEntity(blockHitResult.getBlockPos());
+ if (entity instanceof TrappedChestBlockEntity chestBlockEntity) {
+ chestBlockEntity.startOpen(bot);
+ Bukkit.getScheduler().runTaskLater(CraftScheduler.MINECRAFT, () -> chestBlockEntity.stopOpen(bot), 1);
+ return true;
+ }
+ } else {
+ bot.updateItemInMainHand();
+ return bot.gameMode.useItemOn(bot, bot.level(), bot.getItemInHand(InteractionHand.MAIN_HAND), InteractionHand.MAIN_HAND, (BlockHitResult) result).consumesAction();
+ }
+ bot.updateItemInMainHand();
+ return bot.gameMode.useItemOn(bot, bot.level(), bot.getItemInHand(InteractionHand.MAIN_HAND), InteractionHand.MAIN_HAND, (BlockHitResult) result).consumesAction();
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/top/leavesmc/leaves/bot/agent/actions/UseItemOnOffhandAction.java b/src/main/java/top/leavesmc/leaves/bot/agent/actions/UseItemOnOffhandAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..4ab84fba3624a8e8c4d345c03fe678a012a5c367
index 0000000000000000000000000000000000000000..16ae37e2ffb4189041986e759d563d00a9126ad8
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/bot/agent/actions/UseItemOnOffhandAction.java
@@ -0,0 +1,56 @@
@@ -0,0 +1,40 @@
+package top.leavesmc.leaves.bot.agent.actions;
+
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.InteractionHand;
+import net.minecraft.world.level.ClipContext;
+import net.minecraft.world.level.block.Blocks;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.world.level.block.entity.TrappedChestBlockEntity;
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.phys.BlockHitResult;
+import net.minecraft.world.phys.HitResult;
+import org.bukkit.Bukkit;
+import org.bukkit.craftbukkit.scheduler.CraftScheduler;
+import org.jetbrains.annotations.NotNull;
+import top.leavesmc.leaves.bot.ServerBot;
+import top.leavesmc.leaves.bot.agent.BotAction;
@@ -2977,20 +2885,10 @@ index 0000000000000000000000000000000000000000..4ab84fba3624a8e8c4d345c03fe678a0
+ @Override
+ public boolean doTick(@NotNull ServerBot bot) {
+ HitResult result = bot.getRayTrace(5, ClipContext.Fluid.NONE);
+ if (result instanceof BlockHitResult blockHitResult) {
+ BlockState state = bot.serverLevel().getBlockState(blockHitResult.getBlockPos());
+ if (result.getType() == HitResult.Type.BLOCK) {
+ bot.punch();
+ if (state.getBlock() == Blocks.TRAPPED_CHEST) {
+ BlockEntity entity = bot.serverLevel().getBlockEntity(blockHitResult.getBlockPos());
+ if (entity instanceof TrappedChestBlockEntity chestBlockEntity) {
+ chestBlockEntity.startOpen(bot);
+ Bukkit.getScheduler().runTaskLater(CraftScheduler.MINECRAFT, () -> chestBlockEntity.stopOpen(bot), 1);
+ return true;
+ }
+ } else {
+ bot.updateItemInMainHand();
+ return bot.gameMode.useItemOn(bot, bot.level(), bot.getItemInHand(InteractionHand.OFF_HAND), InteractionHand.OFF_HAND, (BlockHitResult) result).consumesAction();
+ }
+ bot.updateItemInOffHand();
+ return bot.gameMode.useItemOn(bot, bot.level(), bot.getItemInHand(InteractionHand.OFF_HAND), InteractionHand.OFF_HAND, (BlockHitResult) result).consumesAction();
+ }
+ return false;
+ }
@@ -3112,10 +3010,10 @@ index 340eaca64c96180b895a075ce9e44402cd104eed..39e90dcff0de259373d7955021c29397
}
diff --git a/src/main/java/top/leavesmc/leaves/entity/CraftBot.java b/src/main/java/top/leavesmc/leaves/entity/CraftBot.java
new file mode 100644
index 0000000000000000000000000000000000000000..713240da3ba37915b455d952a45ae7f68b8294ee
index 0000000000000000000000000000000000000000..e30ce391f638778fc805ca75287917af99b37443
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/entity/CraftBot.java
@@ -0,0 +1,67 @@
@@ -0,0 +1,60 @@
+package top.leavesmc.leaves.entity;
+
+import org.bukkit.craftbukkit.CraftServer;
@@ -3128,8 +3026,6 @@ index 0000000000000000000000000000000000000000..713240da3ba37915b455d952a45ae7f6
+import top.leavesmc.leaves.bot.agent.BotAction;
+import top.leavesmc.leaves.entity.botaction.LeavesBotAction;
+
+import java.util.UUID;
+
+public class CraftBot extends CraftPlayer implements Bot {
+
+ public CraftBot(CraftServer server, ServerBot entity) {
@@ -3147,11 +3043,6 @@ index 0000000000000000000000000000000000000000..713240da3ba37915b455d952a45ae7f6
+ }
+
+ @Override
+ public @Nullable UUID getCreatePlayerUUID() {
+ return getHandle().createPlayer;
+ }
+
+ @Override
+ public boolean setBotAction(@NotNull String action, @NotNull Player player, @NotNull String[] args) {
+ BotAction botAction = Actions.getForName(action);
+ if (botAction != null) {

View File

@@ -0,0 +1,102 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Tue, 30 Jan 2024 13:08:25 +0000
Subject: [PATCH] Io_uring channel type support
diff --git a/build.gradle.kts b/build.gradle.kts
index 8a926993088d33983f75071b3320dd67c3e857c3..aa1033e0de7d59c32acd2afa58c0b916588b97ed 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -39,6 +39,7 @@ dependencies {
log4jPlugins.annotationProcessorConfigurationName("org.apache.logging.log4j:log4j-core:2.19.0") // Paper - Needed to generate meta for our Log4j plugins
runtimeOnly(log4jPlugins.output)
alsoShade(log4jPlugins.output)
+ implementation("io.netty.incubator:netty-incubator-transport-native-io_uring:0.0.21.Final:linux-x86_64") //Luminol - io_uring Libraries
implementation("io.netty:netty-codec-haproxy:4.1.97.Final") // Paper - Add support for proxy protocol
// Paper end
implementation("org.apache.logging.log4j:log4j-iostreams:2.19.0") // Paper - remove exclusion
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index 610642b0a0c3f17c66ec27ed812b97c68cee1be6..87f5c0fc3f92feecb167c3e28d86a67ba848cb61 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -37,6 +37,7 @@ public class LuminolConfig {
public static boolean fixSpectorTeleportFolia = false;
public static boolean disableRootUserWarning = false;
public static boolean fixDoubleEntitySchedulerRetring = false;
+ public static boolean enableIoUring = false;
public static boolean safeTeleportation = true;
public static boolean enableSandDuping = false;
@@ -185,6 +186,7 @@ public class LuminolConfig {
disableOfflineModeWarning = get("misc.disable_offline_mode_warning",disableOfflineModeWarning);
disableRootUserWarning = get("misc.disable_root_user_warning",disableRootUserWarning);
fixDoubleEntitySchedulerRetring = get("misc.fix_folia_double_entity_scheduler_retring",fixDoubleEntitySchedulerRetring,"Fix https://github.com/PaperMC/Folia/pull/181 on Folia");
+ enableIoUring = get("misc.enable_io_uring_support",enableIoUring);
if (tpsbarEnabled){
initTpsbar();
diff --git a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
index 81090d1b5d67506268a41c6387a1d45302e88a5c..637d321b75dc7b5653ff9aa6134f900c634a19d8 100644
--- a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
+++ b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
@@ -20,9 +20,11 @@ import io.netty.channel.epoll.EpollServerSocketChannel;
import io.netty.channel.local.LocalAddress;
import io.netty.channel.local.LocalServerChannel;
import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
+import io.netty.incubator.channel.uring.IOUring;
+import io.netty.incubator.channel.uring.IOUringEventLoopGroup;
+import io.netty.incubator.channel.uring.IOUringServerSocketChannel;
import io.netty.util.HashedWheelTimer;
import io.netty.util.Timeout;
import io.netty.util.Timer;
@@ -35,6 +37,8 @@ import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import javax.annotation.Nullable;
+
+import me.earthme.luminol.LuminolConfig;
import net.minecraft.CrashReport;
import net.minecraft.ReportedException;
import net.minecraft.network.BandwidthDebugMonitor;
@@ -73,6 +77,10 @@ public class ServerConnectionListener {
}
// Paper end
+ //Luminol start - io_uring support
+ public static final Supplier<IOUringEventLoopGroup> SERVER_IO_URING_WORKER_GROUP = Suppliers.memoize(() -> new IOUringEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty IO_URING Server IO #%d").setDaemon(true).setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(LOGGER)).build()));
+ //Luminol end
+
public ServerConnectionListener(MinecraftServer server) {
this.server = server;
this.running = true;
@@ -89,8 +97,14 @@ public class ServerConnectionListener {
synchronized (this.channels) {
Class oclass;
EventLoopGroup eventloopgroup;
-
- if (Epoll.isAvailable() && this.server.isEpollEnabled()) {
+ //Luminol start - io_uring support
+ if (IOUring.isAvailable() && LuminolConfig.enableIoUring){
+ eventloopgroup = SERVER_IO_URING_WORKER_GROUP.get();
+ oclass = IOUringServerSocketChannel.class;
+ ServerConnectionListener.LOGGER.info("Using io_uring channel type");
+ }
+ else if (Epoll.isAvailable() && this.server.isEpollEnabled()) {
+ //Luminol end
// Paper start
if (address instanceof io.netty.channel.unix.DomainSocketAddress) {
oclass = io.netty.channel.epoll.EpollServerDomainSocketChannel.class;
@@ -100,7 +114,8 @@ public class ServerConnectionListener {
// Paper end
eventloopgroup = (EventLoopGroup) ServerConnectionListener.SERVER_EPOLL_EVENT_GROUP.get();
ServerConnectionListener.LOGGER.info("Using epoll channel type");
- } else {
+ }
+ else {
oclass = NioServerSocketChannel.class;
eventloopgroup = (EventLoopGroup) ServerConnectionListener.SERVER_EVENT_GROUP.get();
ServerConnectionListener.LOGGER.info("Using default channel type");

View File

@@ -0,0 +1,178 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <novau233@163.com>
Date: Thu, 1 Feb 2024 09:51:45 +0000
Subject: [PATCH] Prevent teleportAsync calling during moving event being
handled
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
index 87f5c0fc3f92feecb167c3e28d86a67ba848cb61..0a1a8016f5e51163c2c375a9444d68d3d68544d1 100644
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
@@ -46,6 +46,8 @@ public class LuminolConfig {
public static boolean useVanillaRandomSource = false;
public static boolean fixLargePosMoving = false;
public static boolean warnOnLargeMovingDetected = true;
+ public static boolean preventTeleportAsyncDuringMovingEvent = false;
+ public static boolean throwOnPreventingTeleportAsync = true;
public static RegionFileFormat regionFormatName = RegionFileFormat.ANVIL;
public static int regionFormatLinearCompressionLevel = 1;
@@ -199,6 +201,8 @@ public class LuminolConfig {
useVanillaRandomSource = get("fixes.use_vanilla_random_source",useVanillaRandomSource,"RNG feature related");
fixLargePosMoving = get("fixes.fix_large_pos_moving", fixLargePosMoving,"Fix an entity moving issue on folia which is not fixed yet");
warnOnLargeMovingDetected = get("fixes.warn_on_large_pos_moving",warnOnLargeMovingDetected);
+ preventTeleportAsyncDuringMovingEvent = get("fixes.prevent_teleportasync_during_moving_event",preventTeleportAsyncDuringMovingEvent);
+ throwOnPreventingTeleportAsync = get("fixes.throw_on_preventing_async_teleport",throwOnPreventingTeleportAsync);
regionFormatName = RegionFileFormat.fromString(get("save.region-format.format", regionFormatName.name()));
if (regionFormatName.equals(RegionFileFormat.INVALID)) {
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index ea409d2a03c35990c6857c24305346a6ec7f4bf8..33d2205ba32dd1e11bba92e40d6a4125379b715f 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -326,6 +326,10 @@ public class ServerPlayer extends Player {
public double lastEntitySpawnRadiusSquared = -1.0;
// Paper end - optimise chunk tick iteration
+ //Luminol start - Prevent teleportAsync calling during moving event being handled
+ public boolean handlingMoveEvent = false;
+ //Luminol end
+
public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) {
super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile);
this.chatVisibility = ChatVisiblity.FULL;
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 18745ee33843d668613fd9e7f15d6a79f118280f..9f7eedbac2cbccba4e4cf5e0059cf3a4248438f1 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -688,7 +688,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
if (true) { // Spigot - don't skip any move events
Location oldTo = to.clone();
PlayerMoveEvent event = new PlayerMoveEvent(player, from, to);
+ this.player.handlingMoveEvent = true; //Luminol - Prevent teleportAsync calling during moving event being handled
this.cserver.getPluginManager().callEvent(event);
+ this.player.handlingMoveEvent = false; //Luminol - Prevent teleportAsync calling during moving event being handled
// If the event is cancelled we move the player back to their old location.
if (event.isCancelled()) {
@@ -1592,7 +1594,9 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
if (from.getX() != Double.MAX_VALUE) {
Location oldTo = to.clone();
PlayerMoveEvent event = new PlayerMoveEvent(player, from, to);
+ this.player.handlingMoveEvent = true; //Luminol - Prevent teleportAsync calling during moving event being handled
this.cserver.getPluginManager().callEvent(event);
+ this.player.handlingMoveEvent = false; //Luminol - Prevent teleportAsync calling during moving event being handled
// If the event is cancelled we move the player back to their old location.
if (event.isCancelled()) {
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index e24b55dc96c2e3904e3c03d6bfa769aedf767b3b..1e5eb1277e1b4f2ba51fadbe2d882198ae940ae0 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -3950,6 +3950,18 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
java.util.function.Consumer<Entity> teleportComplete) {
io.papermc.paper.util.TickThread.ensureTickThread(this, "Cannot teleport entity async");
+ //Luminol start - Prevent teleportAsync calling during moving event being handled
+ if (this instanceof ServerPlayer player && LuminolConfig.preventTeleportAsyncDuringMovingEvent){
+ if (player.handlingMoveEvent){
+ if (LuminolConfig.throwOnPreventingTeleportAsync){
+ throw new IllegalStateException("Player " + player.getScoreboardName() + " is trying to teleport to " + pos + " during move event handling!");
+ }
+ MinecraftServer.LOGGER.warn("Player {} is trying to teleport to {} during move event handling!",player.getScoreboardName(),pos);
+ return false;
+ }
+ }
+ //Luminol end
+
if (!ServerLevel.isInSpawnableBounds(new BlockPos(io.papermc.paper.util.CoordinateUtils.getBlockX(pos), io.papermc.paper.util.CoordinateUtils.getBlockY(pos), io.papermc.paper.util.CoordinateUtils.getBlockZ(pos)))) {
return false;
}
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
index 44a6118d3bd67a95180f750c17967561946e2e87..d642f4d42ae7e73642929708a198294e4c5a24d4 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
@@ -5,6 +5,8 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.collect.UnmodifiableIterator;
import com.mojang.datafixers.util.Pair;
+
+import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -20,6 +22,7 @@ import net.minecraft.nbt.NbtUtils;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
+import net.minecraft.server.level.ServerPlayer;
import net.minecraft.tags.BlockTags;
import net.minecraft.util.Mth;
import net.minecraft.world.damagesource.DamageSource;
@@ -426,7 +429,21 @@ public abstract class AbstractMinecart extends Entity {
this.level().getCraftServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleUpdateEvent(vehicle));
if (!from.equals(to)) {
+ //Luminol start - Prevent teleportAsync calling during moving event being handled
+ for (Entity passenger : this.getPassengers()) {
+ if (passenger instanceof ServerPlayer player){
+ player.handlingMoveEvent = true;
+ }
+ }
+ //Luminol end
this.level().getCraftServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleMoveEvent(vehicle, from, to));
+ //Luminol start - Prevent teleportAsync calling during moving event being handled
+ for (Entity passenger : this.getPassengers()) {
+ if (passenger instanceof ServerPlayer player){
+ player.handlingMoveEvent = false;
+ }
+ }
+ //Luminol end
}
// CraftBukkit end
if (this.getMinecartType() == AbstractMinecart.Type.RIDEABLE && this.getDeltaMovement().horizontalDistanceSqr() > 0.01D) {
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
index 5c07da62c82bc70138f6cb5007629d6974be69ac..c68c84af56053cbf7f0c7809a16b60749a4fdd05 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
@@ -2,6 +2,8 @@ package net.minecraft.world.entity.vehicle;
import com.google.common.collect.Lists;
import com.google.common.collect.UnmodifiableIterator;
+
+import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.IntFunction;
@@ -16,6 +18,7 @@ import net.minecraft.network.protocol.game.ServerboundPaddleBoatPacket;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
+import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.tags.FluidTags;
@@ -434,8 +437,22 @@ public class Boat extends Entity implements VariantHolder<Boat.Type> {
server.getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleUpdateEvent(vehicle));
if (this.lastLocation != null && !this.lastLocation.equals(to)) {
+ //Luminol start - Prevent teleportAsync calling during moving event being handled
+ for (Entity passenger : this.getPassengers()) {
+ if (passenger instanceof ServerPlayer player){
+ player.handlingMoveEvent = true;
+ }
+ }
+ //Luminol end
VehicleMoveEvent event = new VehicleMoveEvent(vehicle, this.lastLocation, to);
server.getPluginManager().callEvent(event);
+ //Luminol start - Prevent teleportAsync calling during moving event being handled
+ for (Entity passenger : this.getPassengers()) {
+ if (passenger instanceof ServerPlayer player){
+ player.handlingMoveEvent = false;
+ }
+ }
+ //Luminol end
}
this.lastLocation = vehicle.getLocation();
// CraftBukkit end

BIN
public/image/Luminol_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
public/image/Luminol_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

BIN
public/image/Luminol_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
public/image/Luminol_4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
public/image/Luminol_5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
public/image/Luminol_6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="a" data-name="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 836.86 372.08">
<rect width="836.86" height="372.08" style="fill: #b6ade6; stroke-width: 0px;"/>
<g>
<g>
<path d="M123.68,248.4c4.92-4.92,9.64-9.76,14.54-14.41.74-.7,2.37-.74,3.56-.67,13.41.82,26.8,2.04,40.22,2.49,11.03.37,21.3-2.47,29.91-9.9,1.69-1.46,3.77-2.38,5.58-.43,1.87,2.02.4,3.96-.94,5.57-12.15,14.46-27.56,22.46-46.52,23.52-15.49.87-30.51-2.11-45.48-5.47-.16-.04-.29-.24-.85-.71Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M155.61,204.19c-.41-5.01-.78-10.02-1.23-15.03-1.08-12.23-1.58-24.44.87-36.58,2.24-11.14,7.8-20.1,17.35-26.45.5-.33.99-.84,1.53-.89,1.39-.14,3.27-.61,4.06.07.73.63.8,2.8.33,3.95-2.88,6.97-4.96,14.12-4.9,21.69.08,10.44.39,20.89.82,31.32.12,2.88-.4,5.05-2.58,7.11-5.2,4.91-10.16,10.07-15.22,15.13-.34-.11-.69-.22-1.03-.33Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M118.75,242.21c-1.32-7.02-2.75-13.2-3.6-19.46-1.57-11.63-3.06-23.25-1.52-35.06,2.05-15.79,9.85-28.09,22.06-37.89.61-.49,1.33-1.11,2.04-1.17,1.08-.1,2.6-.13,3.21.5.61.63.74,2.29.36,3.19-.56,1.32-1.78,2.35-2.7,3.52-7.24,9.07-9.87,19.58-9.5,30.96.42,12.92.9,25.85,1.51,38.76.16,3.32-.61,5.88-3.22,8.11-2.86,2.44-5.38,5.28-8.63,8.54Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M182.27,178.13c-.21-15.72-2.76-31.07,3.49-45.83,3.45-8.15,8.41-15.11,15.86-20.01,1.61-1.06,3.8-1.22,5.72-1.8-.2,1.85-.07,3.82-.65,5.54-2.26,6.68-3.26,13.5-3.05,20.53.18,5.76.39,11.53.38,17.29,0,1.47-.34,3.37-1.27,4.34-6.27,6.52-12.74,12.85-19.15,19.23-.19.19-.49.27-1.33.71Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M241.02,131.2c3.42-3.42,6.35-6.35,9.28-9.28.63-.63,1.26-1.27,1.84-1.95,1.59-1.87,2.16-3.99.34-5.9-1.94-2.04-4.13-1.15-5.82.45-3.81,3.62-7.46,7.4-11.81,11.75-.21-2.53-.57-4.35-.47-6.14.61-11.07,8.2-21.21,18.84-24.46,4.29-1.31,8.92-1.92,13.41-2.05,3.84-.11,6.08,2.41,6.31,6.24,1.08,17.79-12.05,33-29.85,31.68-.39-.03-.77-.13-2.06-.36Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M162.64,209.13c4.13-4.13,7.8-8,11.74-11.58.81-.73,2.64-.54,3.98-.45,8.44.55,16.87,1.61,25.3,1.68,6.5.05,13.19-.39,19.46-1.95,4.73-1.18,8.95-4.46,13.38-6.84.6-.32,1.07-1.06,1.68-1.17.99-.18,2.37-.38,2.99.14.59.5.86,2.12.49,2.87-.91,1.84-2.12,3.58-3.45,5.16-8.11,9.63-18.75,14.71-31.1,14.75-14,.05-28-1.2-42-1.91-.56-.03-1.1-.31-2.47-.71Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M199.32,172.64c5.32-5.32,10.01-10.13,14.87-14.76.79-.75,2.33-1,3.52-.98,9.13.13,18.26.43,27.4.55,2.47.03,4.94-.42,7.42-.57,3.8-.23,5.21,1.72,3.6,5.21-2.43,5.24-6.66,8.86-12.05,10.42-4.7,1.36-9.74,2.22-14.62,2.18-9.23-.07-18.45-.95-27.67-1.5-.47-.03-.94-.2-2.47-.54Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M212.27,148.64c-.74-13.61-1.76-26.62,5.71-38.42,3.05-4.82,7.19-8.46,12.11-11.21.88-.49,2.18-.26,3.28-.36-.15,1.08.04,2.4-.51,3.2-6.29,9.12-7.9,19.1-5.85,29.86.16.84-.04,2.11-.59,2.68-4.47,4.63-9.06,9.15-14.15,14.25Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M145.19,162.64c.11,2.23.21,4.47.34,6.7.81,13.7,1.67,27.39,2.36,41.1.07,1.36-.61,3.04-1.51,4.09-2.16,2.53-4.65,4.77-7.52,7.64-.41-6.67-.92-12.58-1.09-18.5-.22-7.75-.5-15.52-.12-23.26.21-4.29,1.48-8.59,2.73-12.75.6-2.01,2.26-3.69,3.44-5.53l1.37.51Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M146.47,225.36c2.62-2.62,4.86-4.98,7.25-7.17.56-.51,1.65-.7,2.47-.65,14.89.88,29.78,1.81,44.67,2.76.85.05,1.68.39,3.28.78-1.37,1.37-2.12,2.73-3.22,3.11-4.19,1.44-8.5,3.65-12.74,3.6-13.41-.16-26.8-1.21-40.2-1.92-.28-.01-.55-.18-1.52-.51Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M223.71,148.26c3.21-3.21,6.37-6.45,9.66-9.57.42-.4,1.49-.36,2.18-.19,10.45,2.44,20.08.53,29.05-5.26,2.06-.95,2.12-.32,3.2-.45-.03,1.08.33,2.37-.14,3.21-3.49,6.31-8.27,11.31-15.57,12.89-9.22,1.99-18.54,1.14-27.82.37-.19-.34-.38-.67-.57-1.01Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M96.66,222.12c-1.04-6.79-1.14-14.5.76-21.62.31-1.14,1.51-2.85,2.34-2.87,1.34-.03,3.19.79,3.93,1.86.94,1.37,1.3,3.33,1.38,5.07.64,13.75,2.61,27.31,5.35,40.77.19.91.18,1.86.33,3.53-5.42-4.74-9.39-9.59-11.15-15.87" style="fill: #fff; stroke-width: 0px;"/>
<path d="M231.81,183.69c-5.89,5.88-12.42,7.48-19.3,7.32-9.23-.21-18.45-.99-27.67-1.54-.36-.02-.71-.21-1.93-.58,2.94-2.94,5.45-5.56,8.11-8.02.54-.5,1.67-.56,2.5-.51,11.4.66,22.81,1.34,34.21,2.11,1.23.08,2.42.71,4.08,1.22Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M135.45,268.18c-6.86-1.92-12.66-5.42-16.69-11.4,13.99,2.98,27.85,5.4,42,5.81,1.69.05,3.52-.34,5.03.19,1.47.52,3.2,1.72,3.77,3.06.83,1.94-1.02,2.96-2.7,3.53-7.14,2.42-14.47,2.53-21.78,1.19" style="fill: #fff; stroke-width: 0px;"/>
<path d="M96.77,264.66c2.32-2.32,4.59-4.67,6.96-6.94,2.24-2.14,4.87-2.5,6.35-.82,1.96,2.22.94,4.34-.74,6.08-4.76,4.92-9.58,9.79-14.5,14.56-1.68,1.63-3.85,2.42-5.81.4-1.92-1.98-1.14-4.12.44-5.85,2.34-2.56,4.88-4.94,7.34-7.4l-.04-.04Z" style="fill: #fff; stroke-width: 0px;"/>
</g>
<g>
<path d="M310.13,149.94v81.38h33.8v9.62h-44.2v-91h10.4Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M353.94,211.3v-43.16h10.4v44.46c0,11.83,5.98,20.54,18.33,20.54s18.33-8.71,18.33-20.54v-44.46h10.4v43.16c0,19.89-10.53,31.2-28.73,31.2s-28.73-11.31-28.73-31.2Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M438.31,168.14v14.04c3.51-10.53,11.57-15.6,21.71-15.6s19.76,5.59,23.4,17.42c3.38-11.7,12.61-17.42,23.4-17.42,13.52,0,25.09,9.36,25.09,29.51v44.85h-10.4v-44.85c0-12.09-5.59-20.28-17.42-20.28-13,0-18.98,9.75-18.98,22.88v42.25h-10.4v-44.85c0-12.09-5.59-20.28-17.42-20.28-13,0-18.98,9.75-18.98,22.88v42.25h-10.4v-72.8h10.4Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M548.16,144.74h10.92v10.4h-10.92v-10.4ZM558.82,168.14v72.8h-10.4v-72.8h10.4Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M586.12,168.14v14.17c3.51-10.53,11.83-15.73,22.36-15.73,13.91,0,25.74,9.36,25.74,29.51v44.85h-10.4v-44.85c0-12.09-5.85-20.28-18.07-20.28-13.39,0-19.63,9.75-19.63,22.88v42.25h-10.4v-72.8h10.4Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M721.58,204.54c0,21.45-15.47,37.96-37.31,37.96s-37.31-16.51-37.31-37.96,15.47-37.96,37.31-37.96,37.31,16.51,37.31,37.96ZM684.27,233.15c16.51,0,26.91-12.48,26.91-28.6s-10.4-28.6-26.91-28.6-26.91,12.48-26.91,28.6,10.4,28.6,26.91,28.6Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M735.36,143.44h10.4v97.5h-10.4v-97.5Z" style="fill: #fff; stroke-width: 0px;"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="f" data-name="6" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 836.86 372.08">
<g>
<path d="M123.68,248.4c4.92-4.92,9.64-9.76,14.54-14.41.74-.7,2.37-.74,3.56-.67,13.41.82,26.8,2.04,40.22,2.49,11.03.37,21.3-2.47,29.91-9.9,1.69-1.46,3.77-2.38,5.58-.43,1.87,2.02.4,3.96-.94,5.57-12.15,14.46-27.56,22.46-46.52,23.52-15.49.87-30.51-2.11-45.48-5.47-.16-.04-.29-.24-.85-.71Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M155.61,204.19c-.41-5.01-.78-10.02-1.23-15.03-1.08-12.23-1.58-24.44.87-36.58,2.24-11.14,7.8-20.1,17.35-26.45.5-.33.99-.84,1.53-.89,1.39-.14,3.27-.61,4.06.07.73.63.8,2.8.33,3.95-2.88,6.97-4.96,14.12-4.9,21.69.08,10.44.39,20.89.82,31.32.12,2.88-.4,5.05-2.58,7.11-5.2,4.91-10.16,10.07-15.22,15.13-.34-.11-.69-.22-1.03-.33Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M118.75,242.21c-1.32-7.02-2.75-13.2-3.6-19.46-1.57-11.63-3.06-23.25-1.52-35.06,2.05-15.79,9.85-28.09,22.06-37.89.61-.49,1.33-1.11,2.04-1.17,1.08-.1,2.6-.13,3.21.5.61.63.74,2.29.36,3.19-.56,1.32-1.78,2.35-2.7,3.52-7.24,9.07-9.87,19.58-9.5,30.96.42,12.92.9,25.85,1.51,38.76.16,3.32-.61,5.88-3.22,8.11-2.86,2.44-5.38,5.28-8.63,8.54Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M182.27,178.13c-.21-15.72-2.76-31.07,3.49-45.83,3.45-8.15,8.41-15.11,15.86-20.01,1.61-1.06,3.8-1.22,5.72-1.8-.2,1.85-.07,3.82-.65,5.54-2.26,6.68-3.26,13.5-3.05,20.53.18,5.76.39,11.53.38,17.29,0,1.47-.34,3.37-1.27,4.34-6.27,6.52-12.74,12.85-19.15,19.23-.19.19-.49.27-1.33.71Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M241.02,131.2c3.42-3.42,6.35-6.35,9.28-9.28.63-.63,1.26-1.27,1.84-1.95,1.59-1.87,2.16-3.99.34-5.9-1.94-2.04-4.13-1.15-5.82.45-3.81,3.62-7.46,7.4-11.81,11.75-.21-2.53-.57-4.35-.47-6.14.61-11.07,8.2-21.21,18.84-24.46,4.29-1.31,8.92-1.92,13.41-2.05,3.84-.11,6.08,2.41,6.31,6.24,1.08,17.79-12.05,33-29.85,31.68-.39-.03-.77-.13-2.06-.36Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M162.64,209.13c4.13-4.13,7.8-8,11.74-11.58.81-.73,2.64-.54,3.98-.45,8.44.55,16.87,1.61,25.3,1.68,6.5.05,13.19-.39,19.46-1.95,4.73-1.18,8.95-4.46,13.38-6.84.6-.32,1.07-1.06,1.68-1.17.99-.18,2.37-.38,2.99.14.59.5.86,2.12.49,2.87-.91,1.84-2.12,3.58-3.45,5.16-8.11,9.63-18.75,14.71-31.1,14.75-14,.05-28-1.2-42-1.91-.56-.03-1.1-.31-2.47-.71Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M199.32,172.64c5.32-5.32,10.01-10.13,14.87-14.76.79-.75,2.33-1,3.52-.98,9.13.13,18.26.43,27.4.55,2.47.03,4.94-.42,7.42-.57,3.8-.23,5.21,1.72,3.6,5.21-2.43,5.24-6.66,8.86-12.05,10.42-4.7,1.36-9.74,2.22-14.62,2.18-9.23-.07-18.45-.95-27.67-1.5-.47-.03-.94-.2-2.47-.54Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M212.27,148.64c-.74-13.61-1.76-26.62,5.71-38.42,3.05-4.82,7.19-8.46,12.11-11.21.88-.49,2.18-.26,3.28-.36-.15,1.08.04,2.4-.51,3.2-6.29,9.12-7.9,19.1-5.85,29.86.16.84-.04,2.11-.59,2.68-4.47,4.63-9.06,9.15-14.15,14.25Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M145.19,162.64c.11,2.23.21,4.47.34,6.7.81,13.7,1.67,27.39,2.36,41.1.07,1.36-.61,3.04-1.51,4.09-2.16,2.53-4.65,4.77-7.52,7.64-.41-6.67-.92-12.58-1.09-18.5-.22-7.75-.5-15.52-.12-23.26.21-4.29,1.48-8.59,2.73-12.75.6-2.01,2.26-3.69,3.44-5.53l1.37.51Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M146.47,225.36c2.62-2.62,4.86-4.98,7.25-7.17.56-.51,1.65-.7,2.47-.65,14.89.88,29.78,1.81,44.67,2.76.85.05,1.68.39,3.28.78-1.37,1.37-2.12,2.73-3.22,3.11-4.19,1.44-8.5,3.65-12.74,3.6-13.41-.16-26.8-1.21-40.2-1.92-.28-.01-.55-.18-1.52-.51Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M223.71,148.26c3.21-3.21,6.37-6.45,9.66-9.57.42-.4,1.49-.36,2.18-.19,10.45,2.44,20.08.53,29.05-5.26,2.06-.95,2.12-.32,3.2-.45-.03,1.08.33,2.37-.14,3.21-3.49,6.31-8.27,11.31-15.57,12.89-9.22,1.99-18.54,1.14-27.82.37-.19-.34-.38-.67-.57-1.01Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M96.66,222.12c-1.04-6.79-1.14-14.5.76-21.62.31-1.14,1.51-2.85,2.34-2.87,1.34-.03,3.19.79,3.93,1.86.94,1.37,1.3,3.33,1.38,5.07.64,13.75,2.61,27.31,5.35,40.77.19.91.18,1.86.33,3.53-5.42-4.74-9.39-9.59-11.15-15.87" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M231.81,183.69c-5.89,5.88-12.42,7.48-19.3,7.32-9.23-.21-18.45-.99-27.67-1.54-.36-.02-.71-.21-1.93-.58,2.94-2.94,5.45-5.56,8.11-8.02.54-.5,1.67-.56,2.5-.51,11.4.66,22.81,1.34,34.21,2.11,1.23.08,2.42.71,4.08,1.22Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M135.45,268.18c-6.86-1.92-12.66-5.42-16.69-11.4,13.99,2.98,27.85,5.4,42,5.81,1.69.05,3.52-.34,5.03.19,1.47.52,3.2,1.72,3.77,3.06.83,1.94-1.02,2.96-2.7,3.53-7.14,2.42-14.47,2.53-21.78,1.19" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M96.77,264.66c2.32-2.32,4.59-4.67,6.96-6.94,2.24-2.14,4.87-2.5,6.35-.82,1.96,2.22.94,4.34-.74,6.08-4.76,4.92-9.58,9.79-14.5,14.56-1.68,1.63-3.85,2.42-5.81.4-1.92-1.98-1.14-4.12.44-5.85,2.34-2.56,4.88-4.94,7.34-7.4l-.04-.04Z" style="fill: #b6ade6; stroke-width: 0px;"/>
</g>
<g>
<path d="M310.13,149.94v81.38h33.8v9.62h-44.2v-91h10.4Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M353.94,211.3v-43.16h10.4v44.46c0,11.83,5.98,20.54,18.33,20.54s18.33-8.71,18.33-20.54v-44.46h10.4v43.16c0,19.89-10.53,31.2-28.73,31.2s-28.73-11.31-28.73-31.2Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M438.31,168.14v14.04c3.51-10.53,11.57-15.6,21.71-15.6s19.76,5.59,23.4,17.42c3.38-11.7,12.61-17.42,23.4-17.42,13.52,0,25.09,9.36,25.09,29.51v44.85h-10.4v-44.85c0-12.09-5.59-20.28-17.42-20.28-13,0-18.98,9.75-18.98,22.88v42.25h-10.4v-44.85c0-12.09-5.59-20.28-17.42-20.28-13,0-18.98,9.75-18.98,22.88v42.25h-10.4v-72.8h10.4Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M548.16,144.74h10.92v10.4h-10.92v-10.4ZM558.82,168.14v72.8h-10.4v-72.8h10.4Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M586.12,168.14v14.17c3.51-10.53,11.83-15.73,22.36-15.73,13.91,0,25.74,9.36,25.74,29.51v44.85h-10.4v-44.85c0-12.09-5.85-20.28-18.07-20.28-13.39,0-19.63,9.75-19.63,22.88v42.25h-10.4v-72.8h10.4Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M721.58,204.54c0,21.45-15.47,37.96-37.31,37.96s-37.31-16.51-37.31-37.96,15.47-37.96,37.31-37.96,37.31,16.51,37.31,37.96ZM684.27,233.15c16.51,0,26.91-12.48,26.91-28.6s-10.4-28.6-26.91-28.6-26.91,12.48-26.91,28.6,10.4,28.6,26.91,28.6Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M735.36,143.44h10.4v97.5h-10.4v-97.5Z" style="fill: #b6ade6; stroke-width: 0px;"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="b" data-name="2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 287.08 287.08">
<rect x="0" width="287.08" height="287.08" style="fill: #b6ade6; stroke-width: 0px;"/>
<g>
<path d="M45.03,194.01v37.56h15.6v4.44h-20.4v-42h4.8Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M65.25,222.33v-19.92h4.8v20.52c0,5.46,2.76,9.48,8.46,9.48s8.46-4.02,8.46-9.48v-20.52h4.8v19.92c0,9.18-4.86,14.4-13.26,14.4s-13.26-5.22-13.26-14.4Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M104.19,202.41v6.48c1.62-4.86,5.34-7.2,10.02-7.2s9.12,2.58,10.8,8.04c1.56-5.4,5.82-8.04,10.8-8.04,6.24,0,11.58,4.32,11.58,13.62v20.7h-4.8v-20.7c0-5.58-2.58-9.36-8.04-9.36-6,0-8.76,4.5-8.76,10.56v19.5h-4.8v-20.7c0-5.58-2.58-9.36-8.04-9.36-6,0-8.76,4.5-8.76,10.56v19.5h-4.8v-33.6h4.8Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M154.89,191.61h5.04v4.8h-5.04v-4.8ZM159.81,202.41v33.6h-4.8v-33.6h4.8Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M172.41,202.41v6.54c1.62-4.86,5.46-7.26,10.32-7.26,6.42,0,11.88,4.32,11.88,13.62v20.7h-4.8v-20.7c0-5.58-2.7-9.36-8.34-9.36-6.18,0-9.06,4.5-9.06,10.56v19.5h-4.8v-33.6h4.8Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M234.93,219.21c0,9.9-7.14,17.52-17.22,17.52s-17.22-7.62-17.22-17.52,7.14-17.52,17.22-17.52,17.22,7.62,17.22,17.52ZM217.71,232.41c7.62,0,12.42-5.76,12.42-13.2s-4.8-13.2-12.42-13.2-12.42,5.76-12.42,13.2,4.8,13.2,12.42,13.2Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M241.29,191.01h4.8v45h-4.8v-45Z" style="fill: #fff; stroke-width: 0px;"/>
</g>
<g>
<path d="M109.11,163.11c3.48-3.48,6.81-6.9,10.27-10.18.53-.5,1.67-.52,2.51-.47,9.47.58,18.93,1.44,28.41,1.76,7.79.26,15.04-1.74,21.13-6.99,1.2-1.03,2.66-1.68,3.94-.3,1.32,1.43.28,2.8-.67,3.93-8.58,10.21-19.47,15.86-32.86,16.62-10.95.62-21.55-1.49-32.13-3.86-.12-.03-.21-.17-.6-.5Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M131.67,131.88c-.29-3.54-.55-7.08-.87-10.62-.77-8.64-1.11-17.26.61-25.84,1.58-7.87,5.51-14.2,12.25-18.68.35-.23.7-.59,1.08-.63.98-.1,2.31-.43,2.87.05.52.45.57,1.98.23,2.79-2.03,4.92-3.5,9.98-3.46,15.32.06,7.38.27,14.75.58,22.12.08,2.04-.28,3.57-1.82,5.03-3.67,3.47-7.18,7.11-10.75,10.69-.24-.08-.48-.16-.73-.23Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M105.63,158.74c-.93-4.96-1.94-9.32-2.54-13.74-1.11-8.21-2.16-16.43-1.07-24.77,1.45-11.15,6.96-19.84,15.58-26.76.43-.35.94-.78,1.44-.83.77-.07,1.83-.09,2.26.35.43.45.52,1.62.25,2.25-.4.93-1.26,1.66-1.91,2.48-5.11,6.41-6.97,13.83-6.71,21.87.3,9.13.64,18.26,1.07,27.38.11,2.34-.43,4.15-2.27,5.73-2.02,1.73-3.8,3.73-6.1,6.03Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M150.5,113.47c-.15-11.1-1.95-21.95,2.47-32.38,2.44-5.76,5.94-10.67,11.2-14.13,1.13-.75,2.68-.86,4.04-1.27-.14,1.31-.05,2.7-.46,3.92-1.6,4.72-2.3,9.54-2.15,14.5.12,4.07.28,8.14.27,12.21,0,1.04-.24,2.38-.9,3.07-4.43,4.61-9,9.08-13.53,13.58-.13.13-.34.19-.94.5Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M192,80.32c2.42-2.42,4.49-4.48,6.55-6.56.45-.45.89-.9,1.3-1.38,1.12-1.32,1.53-2.82.24-4.17-1.37-1.44-2.92-.81-4.11.32-2.69,2.55-5.27,5.23-8.34,8.3-.15-1.79-.4-3.07-.33-4.33.43-7.82,5.79-14.98,13.31-17.28,3.03-.93,6.3-1.36,9.48-1.45,2.72-.08,4.29,1.7,4.46,4.41.76,12.57-8.51,23.31-21.09,22.38-.27-.02-.54-.09-1.46-.25Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M136.63,135.37c2.92-2.92,5.51-5.65,8.3-8.18.57-.52,1.86-.38,2.81-.32,5.96.39,11.91,1.14,17.88,1.19,4.59.04,9.32-.27,13.74-1.37,3.34-.83,6.32-3.15,9.45-4.83.43-.23.76-.75,1.19-.83.7-.13,1.68-.27,2.11.1.42.35.61,1.5.35,2.02-.64,1.3-1.5,2.53-2.44,3.65-5.73,6.81-13.24,10.39-21.97,10.42-9.89.03-19.78-.85-29.67-1.35-.39-.02-.78-.22-1.74-.5Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M162.55,109.59c3.75-3.75,7.07-7.15,10.51-10.42.56-.53,1.65-.71,2.49-.69,6.45.09,12.9.3,19.35.39,1.75.02,3.49-.3,5.24-.4,2.68-.16,3.68,1.22,2.54,3.68-1.72,3.7-4.7,6.26-8.51,7.36-3.32.96-6.88,1.57-10.33,1.54-6.52-.05-13.03-.67-19.55-1.06-.33-.02-.66-.14-1.75-.38Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M171.69,92.64c-.52-9.61-1.24-18.81,4.03-27.14,2.15-3.4,5.08-5.97,8.55-7.92.62-.35,1.54-.18,2.32-.25-.11.76.03,1.7-.36,2.26-4.44,6.45-5.58,13.49-4.13,21.09.11.6-.03,1.49-.42,1.89-3.16,3.27-6.4,6.46-10,10.06Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M124.31,102.53c.08,1.58.15,3.16.24,4.73.57,9.68,1.18,19.35,1.67,29.03.05.96-.43,2.15-1.07,2.89-1.53,1.79-3.29,3.37-5.31,5.4-.29-4.71-.65-8.89-.77-13.07-.16-5.47-.35-10.97-.08-16.43.15-3.03,1.05-6.07,1.93-9.01.43-1.42,1.6-2.61,2.43-3.9l.97.36Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M125.21,146.83c1.85-1.85,3.44-3.52,5.12-5.06.4-.36,1.17-.49,1.75-.46,10.52.62,21.04,1.28,31.56,1.95.6.04,1.18.27,2.32.55-.97.97-1.5,1.93-2.27,2.2-2.96,1.02-6,2.58-9,2.54-9.47-.11-18.93-.85-28.4-1.36-.2-.01-.39-.13-1.07-.36Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M179.77,92.37c2.26-2.26,4.5-4.55,6.82-6.76.3-.28,1.05-.25,1.54-.14,7.39,1.73,14.18.37,20.52-3.71,1.46-.67,1.5-.22,2.26-.32-.02.76.23,1.68-.1,2.27-2.47,4.45-5.85,7.99-11,9.11-6.52,1.41-13.1.81-19.65.26-.13-.24-.27-.48-.4-.71Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M90.03,144.54c-.74-4.8-.81-10.24.53-15.28.22-.81,1.07-2.02,1.65-2.03.94-.02,2.25.55,2.78,1.31.67.97.92,2.35.98,3.58.45,9.71,1.84,19.29,3.78,28.8.13.64.13,1.31.23,2.49-3.83-3.35-6.63-6.77-7.88-11.21" style="fill: #fff; stroke-width: 0px;"/>
<path d="M185.5,117.4c-4.16,4.15-8.77,5.28-13.63,5.17-6.52-.15-13.03-.7-19.54-1.09-.26-.02-.5-.15-1.36-.41,2.08-2.08,3.85-3.93,5.73-5.66.38-.35,1.18-.4,1.77-.36,8.06.46,16.11.95,24.16,1.49.87.06,1.71.5,2.88.86Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M117.43,177.08c-4.85-1.36-8.94-3.83-11.79-8.05,9.88,2.11,19.67,3.81,29.67,4.11,1.19.03,2.48-.24,3.55.13,1.04.37,2.26,1.21,2.66,2.16.58,1.37-.72,2.09-1.91,2.49-5.05,1.71-10.22,1.79-15.39.84" style="fill: #fff; stroke-width: 0px;"/>
<path d="M90.1,174.6c1.64-1.64,3.24-3.3,4.92-4.9,1.58-1.51,3.44-1.77,4.49-.58,1.39,1.57.67,3.07-.52,4.3-3.36,3.48-6.77,6.92-10.24,10.29-1.19,1.15-2.72,1.71-4.1.29-1.35-1.4-.81-2.91.31-4.13,1.65-1.81,3.45-3.49,5.19-5.23l-.03-.03Z" style="fill: #fff; stroke-width: 0px;"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="c" data-name="3" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 287.08 287.08">
<rect width="287.08" height="287.08" style="fill: #b6ade6; stroke-width: 0px;"/>
<g>
<path d="M92.91,203.79c4.69-4.69,9.19-9.31,13.87-13.74.71-.67,2.26-.71,3.39-.64,12.79.78,25.56,1.94,38.36,2.37,10.52.36,20.31-2.35,28.53-9.44,1.61-1.39,3.59-2.27,5.32-.41,1.78,1.92.38,3.78-.9,5.31-11.59,13.79-26.29,21.42-44.38,22.44-14.78.83-29.1-2.01-43.38-5.21-.16-.04-.28-.22-.81-.68Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M123.36,161.63c-.39-4.78-.75-9.56-1.17-14.33-1.03-11.66-1.5-23.31.83-34.89,2.14-10.62,7.44-19.17,16.55-25.23.47-.31.95-.8,1.46-.85,1.32-.13,3.12-.59,3.88.07.7.6.76,2.67.31,3.77-2.75,6.65-4.73,13.47-4.68,20.69.07,9.96.37,19.92.78,29.87.11,2.75-.38,4.82-2.46,6.79-4.96,4.69-9.69,9.6-14.52,14.43-.33-.11-.65-.21-.98-.32Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M88.21,197.89c-1.26-6.7-2.62-12.59-3.43-18.56-1.5-11.09-2.92-22.18-1.45-33.45,1.96-15.06,9.4-26.79,21.04-36.14.59-.47,1.27-1.06,1.95-1.12,1.03-.09,2.48-.12,3.06.48.58.6.71,2.19.34,3.04-.54,1.26-1.69,2.25-2.58,3.35-6.9,8.65-9.41,18.68-9.06,29.54.4,12.33.86,24.65,1.44,36.97.15,3.16-.58,5.61-3.07,7.74-2.73,2.33-5.13,5.04-8.23,8.14Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M148.8,136.77c-.2-14.99-2.63-29.64,3.33-43.72,3.29-7.77,8.02-14.41,15.12-19.08,1.53-1.01,3.62-1.17,5.46-1.72-.19,1.77-.07,3.64-.62,5.29-2.16,6.37-3.11,12.88-2.91,19.58.17,5.5.37,11,.36,16.49,0,1.4-.32,3.21-1.21,4.14-5.98,6.22-12.15,12.25-18.27,18.34-.18.18-.46.25-1.27.68Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M204.83,92c3.27-3.27,6.06-6.06,8.85-8.85.6-.6,1.2-1.21,1.75-1.86,1.52-1.79,2.06-3.8.32-5.63-1.85-1.95-3.94-1.09-5.55.43-3.63,3.45-7.12,7.06-11.27,11.21-.2-2.41-.55-4.14-.45-5.85.58-10.56,7.82-20.23,17.97-23.33,4.09-1.25,8.51-1.83,12.79-1.95,3.67-.1,5.8,2.3,6.02,5.95,1.03,16.97-11.49,31.48-28.47,30.22-.37-.03-.73-.12-1.97-.34Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M130.07,166.33c3.94-3.94,7.44-7.63,11.2-11.04.77-.7,2.52-.51,3.8-.43,8.05.53,16.09,1.54,24.14,1.6,6.2.05,12.58-.37,18.56-1.86,4.52-1.12,8.53-4.25,12.76-6.52.58-.31,1.02-1.01,1.6-1.12.95-.17,2.26-.36,2.85.13.56.47.82,2.02.47,2.73-.87,1.76-2.02,3.42-3.29,4.93-7.74,9.19-17.88,14.03-29.66,14.07-13.35.05-26.71-1.15-40.06-1.82-.53-.03-1.05-.29-2.36-.68Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M165.06,131.53c5.07-5.07,9.55-9.66,14.19-14.08.75-.72,2.23-.95,3.36-.94,8.71.12,17.42.41,26.13.52,2.36.03,4.72-.41,7.08-.55,3.62-.22,4.97,1.64,3.43,4.97-2.32,5-6.35,8.45-11.49,9.94-4.49,1.3-9.29,2.12-13.95,2.08-8.8-.07-17.6-.9-26.39-1.43-.45-.03-.89-.19-2.36-.52Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M177.41,108.64c-.71-12.98-1.68-25.39,5.45-36.64,2.91-4.59,6.86-8.07,11.55-10.69.84-.47,2.08-.24,3.13-.34-.15,1.03.04,2.29-.49,3.06-6,8.7-7.54,18.22-5.58,28.48.15.8-.04,2.01-.56,2.55-4.26,4.42-8.64,8.73-13.5,13.59Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M113.43,121.99c.11,2.13.2,4.26.32,6.39.77,13.07,1.59,26.13,2.25,39.2.06,1.29-.59,2.9-1.44,3.91-2.06,2.41-4.44,4.55-7.17,7.28-.39-6.36-.88-12-1.04-17.65-.21-7.39-.48-14.81-.11-22.18.2-4.1,1.41-8.2,2.6-12.17.57-1.91,2.15-3.52,3.28-5.27l1.31.49Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M114.65,181.82c2.5-2.5,4.64-4.75,6.92-6.84.54-.49,1.57-.67,2.36-.62,14.21.84,28.41,1.73,42.61,2.64.81.05,1.6.37,3.13.74-1.31,1.31-2.03,2.61-3.07,2.97-4,1.37-8.11,3.48-12.15,3.43-12.79-.15-25.57-1.15-38.35-1.83-.27-.01-.53-.17-1.45-.49Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M188.32,108.28c3.06-3.06,6.08-6.15,9.21-9.13.4-.38,1.42-.34,2.08-.19,9.97,2.33,19.15.5,27.71-5.01,1.97-.91,2.03-.3,3.06-.43-.03,1.03.31,2.26-.13,3.07-3.33,6.01-7.89,10.79-14.85,12.29-8.8,1.9-17.69,1.09-26.54.35-.18-.32-.36-.64-.54-.96Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M67.14,178.73c-.99-6.48-1.09-13.83.72-20.63.29-1.09,1.44-2.72,2.23-2.74,1.28-.03,3.04.75,3.75,1.77.9,1.3,1.24,3.18,1.32,4.83.61,13.11,2.49,26.05,5.11,38.89.18.87.17,1.77.32,3.36-5.17-4.52-8.95-9.14-10.64-15.14" style="fill: #fff; stroke-width: 0px;"/>
<path d="M196.05,142.07c-5.62,5.61-11.85,7.13-18.41,6.99-8.8-.2-17.59-.94-26.39-1.47-.34-.02-.68-.2-1.84-.55,2.81-2.81,5.2-5.31,7.74-7.65.52-.48,1.59-.54,2.39-.49,10.88.63,21.75,1.28,32.63,2.01,1.17.08,2.31.67,3.89,1.16Z" style="fill: #fff; stroke-width: 0px;"/>
<path d="M104.14,222.66c-6.55-1.83-12.07-5.17-15.92-10.87,13.35,2.84,26.56,5.15,40.06,5.54,1.61.05,3.35-.33,4.79.18,1.4.5,3.05,1.64,3.6,2.92.79,1.85-.98,2.82-2.58,3.37-6.81,2.31-13.81,2.41-20.78,1.14" style="fill: #fff; stroke-width: 0px;"/>
<path d="M67.24,219.31c2.21-2.21,4.38-4.46,6.64-6.62,2.14-2.04,4.64-2.39,6.06-.79,1.87,2.12.9,4.14-.71,5.8-4.54,4.69-9.14,9.34-13.83,13.89-1.6,1.55-3.67,2.31-5.54.39-1.83-1.88-1.09-3.93.42-5.58,2.23-2.44,4.66-4.71,7-7.06l-.04-.04Z" style="fill: #fff; stroke-width: 0px;"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="d" data-name="4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 287.08 287.08">
<g>
<path d="M45.03,194.01v37.56h15.6v4.44h-20.4v-42h4.8Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M65.25,222.33v-19.92h4.8v20.52c0,5.46,2.76,9.48,8.46,9.48s8.46-4.02,8.46-9.48v-20.52h4.8v19.92c0,9.18-4.86,14.4-13.26,14.4s-13.26-5.22-13.26-14.4Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M104.19,202.41v6.48c1.62-4.86,5.34-7.2,10.02-7.2s9.12,2.58,10.8,8.04c1.56-5.4,5.82-8.04,10.8-8.04,6.24,0,11.58,4.32,11.58,13.62v20.7h-4.8v-20.7c0-5.58-2.58-9.36-8.04-9.36-6,0-8.76,4.5-8.76,10.56v19.5h-4.8v-20.7c0-5.58-2.58-9.36-8.04-9.36-6,0-8.76,4.5-8.76,10.56v19.5h-4.8v-33.6h4.8Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M154.89,191.61h5.04v4.8h-5.04v-4.8ZM159.81,202.41v33.6h-4.8v-33.6h4.8Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M172.41,202.41v6.54c1.62-4.86,5.46-7.26,10.32-7.26,6.42,0,11.88,4.32,11.88,13.62v20.7h-4.8v-20.7c0-5.58-2.7-9.36-8.34-9.36-6.18,0-9.06,4.5-9.06,10.56v19.5h-4.8v-33.6h4.8Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M234.93,219.21c0,9.9-7.14,17.52-17.22,17.52s-17.22-7.62-17.22-17.52,7.14-17.52,17.22-17.52,17.22,7.62,17.22,17.52ZM217.71,232.41c7.62,0,12.42-5.76,12.42-13.2s-4.8-13.2-12.42-13.2-12.42,5.76-12.42,13.2,4.8,13.2,12.42,13.2Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M241.29,191.01h4.8v45h-4.8v-45Z" style="fill: #b6ade6; stroke-width: 0px;"/>
</g>
<g>
<path d="M109.11,163.11c3.48-3.48,6.81-6.9,10.27-10.18.53-.5,1.67-.52,2.51-.47,9.47.58,18.93,1.44,28.41,1.76,7.79.26,15.04-1.74,21.13-6.99,1.2-1.03,2.66-1.68,3.94-.3,1.32,1.43.28,2.8-.67,3.93-8.58,10.21-19.47,15.86-32.86,16.62-10.95.62-21.55-1.49-32.13-3.86-.12-.03-.21-.17-.6-.5Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M131.67,131.88c-.29-3.54-.55-7.08-.87-10.62-.77-8.64-1.11-17.26.61-25.84,1.58-7.87,5.51-14.2,12.25-18.68.35-.23.7-.59,1.08-.63.98-.1,2.31-.43,2.87.05.52.45.57,1.98.23,2.79-2.03,4.92-3.5,9.98-3.46,15.32.06,7.38.27,14.75.58,22.12.08,2.04-.28,3.57-1.82,5.03-3.67,3.47-7.18,7.11-10.75,10.69-.24-.08-.48-.16-.73-.23Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M105.63,158.74c-.93-4.96-1.94-9.32-2.54-13.74-1.11-8.21-2.16-16.43-1.07-24.77,1.45-11.15,6.96-19.84,15.58-26.76.43-.35.94-.78,1.44-.83.77-.07,1.83-.09,2.26.35.43.45.52,1.62.25,2.25-.4.93-1.26,1.66-1.91,2.48-5.11,6.41-6.97,13.83-6.71,21.87.3,9.13.64,18.26,1.07,27.38.11,2.34-.43,4.15-2.27,5.73-2.02,1.73-3.8,3.73-6.1,6.03Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M150.5,113.47c-.15-11.1-1.95-21.95,2.47-32.38,2.44-5.76,5.94-10.67,11.2-14.13,1.13-.75,2.68-.86,4.04-1.27-.14,1.31-.05,2.7-.46,3.92-1.6,4.72-2.3,9.54-2.15,14.5.12,4.07.28,8.14.27,12.21,0,1.04-.24,2.38-.9,3.07-4.43,4.61-9,9.08-13.53,13.58-.13.13-.34.19-.94.5Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M192,80.32c2.42-2.42,4.49-4.48,6.55-6.56.45-.45.89-.9,1.3-1.38,1.12-1.32,1.53-2.82.24-4.17-1.37-1.44-2.92-.81-4.11.32-2.69,2.55-5.27,5.23-8.34,8.3-.15-1.79-.4-3.07-.33-4.33.43-7.82,5.79-14.98,13.31-17.28,3.03-.93,6.3-1.36,9.48-1.45,2.72-.08,4.29,1.7,4.46,4.41.76,12.57-8.51,23.31-21.09,22.38-.27-.02-.54-.09-1.46-.25Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M136.63,135.37c2.92-2.92,5.51-5.65,8.3-8.18.57-.52,1.86-.38,2.81-.32,5.96.39,11.91,1.14,17.88,1.19,4.59.04,9.32-.27,13.74-1.37,3.34-.83,6.32-3.15,9.45-4.83.43-.23.76-.75,1.19-.83.7-.13,1.68-.27,2.11.1.42.35.61,1.5.35,2.02-.64,1.3-1.5,2.53-2.44,3.65-5.73,6.81-13.24,10.39-21.97,10.42-9.89.03-19.78-.85-29.67-1.35-.39-.02-.78-.22-1.74-.5Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M162.55,109.59c3.75-3.75,7.07-7.15,10.51-10.42.56-.53,1.65-.71,2.49-.69,6.45.09,12.9.3,19.35.39,1.75.02,3.49-.3,5.24-.4,2.68-.16,3.68,1.22,2.54,3.68-1.72,3.7-4.7,6.26-8.51,7.36-3.32.96-6.88,1.57-10.33,1.54-6.52-.05-13.03-.67-19.55-1.06-.33-.02-.66-.14-1.75-.38Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M171.69,92.64c-.52-9.61-1.24-18.81,4.03-27.14,2.15-3.4,5.08-5.97,8.55-7.92.62-.35,1.54-.18,2.32-.25-.11.76.03,1.7-.36,2.26-4.44,6.45-5.58,13.49-4.13,21.09.11.6-.03,1.49-.42,1.89-3.16,3.27-6.4,6.46-10,10.06Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M124.31,102.53c.08,1.58.15,3.16.24,4.73.57,9.68,1.18,19.35,1.67,29.03.05.96-.43,2.15-1.07,2.89-1.53,1.79-3.29,3.37-5.31,5.4-.29-4.71-.65-8.89-.77-13.07-.16-5.47-.35-10.97-.08-16.43.15-3.03,1.05-6.07,1.93-9.01.43-1.42,1.6-2.61,2.43-3.9l.97.36Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M125.21,146.83c1.85-1.85,3.44-3.52,5.12-5.06.4-.36,1.17-.49,1.75-.46,10.52.62,21.04,1.28,31.56,1.95.6.04,1.18.27,2.32.55-.97.97-1.5,1.93-2.27,2.2-2.96,1.02-6,2.58-9,2.54-9.47-.11-18.93-.85-28.4-1.36-.2-.01-.39-.13-1.07-.36Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M179.77,92.37c2.26-2.26,4.5-4.55,6.82-6.76.3-.28,1.05-.25,1.54-.14,7.39,1.73,14.18.37,20.52-3.71,1.46-.67,1.5-.22,2.26-.32-.02.76.23,1.68-.1,2.27-2.47,4.45-5.85,7.99-11,9.11-6.52,1.41-13.1.81-19.65.26-.13-.24-.27-.48-.4-.71Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M90.03,144.54c-.74-4.8-.81-10.24.53-15.28.22-.81,1.07-2.02,1.65-2.03.94-.02,2.25.55,2.78,1.31.67.97.92,2.35.98,3.58.45,9.71,1.84,19.29,3.78,28.8.13.64.13,1.31.23,2.49-3.83-3.35-6.63-6.77-7.88-11.21" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M185.5,117.4c-4.16,4.15-8.77,5.28-13.63,5.17-6.52-.15-13.03-.7-19.54-1.09-.26-.02-.5-.15-1.36-.41,2.08-2.08,3.85-3.93,5.73-5.66.38-.35,1.18-.4,1.77-.36,8.06.46,16.11.95,24.16,1.49.87.06,1.71.5,2.88.86Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M117.43,177.08c-4.85-1.36-8.94-3.83-11.79-8.05,9.88,2.11,19.67,3.81,29.67,4.11,1.19.03,2.48-.24,3.55.13,1.04.37,2.26,1.21,2.66,2.16.58,1.37-.72,2.09-1.91,2.49-5.05,1.71-10.22,1.79-15.39.84" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M90.1,174.6c1.64-1.64,3.24-3.3,4.92-4.9,1.58-1.51,3.44-1.77,4.49-.58,1.39,1.57.67,3.07-.52,4.3-3.36,3.48-6.77,6.92-10.24,10.29-1.19,1.15-2.72,1.71-4.1.29-1.35-1.4-.81-2.91.31-4.13,1.65-1.81,3.45-3.49,5.19-5.23l-.03-.03Z" style="fill: #b6ade6; stroke-width: 0px;"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="e" data-name="5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 287.08 287.08">
<path d="M92.91,205.18c4.69-4.69,9.19-9.31,13.87-13.74.71-.67,2.26-.71,3.39-.64,12.79.78,25.56,1.94,38.36,2.37,10.52.36,20.31-2.35,28.53-9.44,1.61-1.39,3.59-2.27,5.32-.41,1.78,1.92.38,3.78-.9,5.31-11.59,13.79-26.29,21.42-44.38,22.44-14.78.83-29.1-2.01-43.38-5.21-.16-.04-.28-.22-.81-.68Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M123.36,163.01c-.39-4.78-.75-9.56-1.17-14.33-1.03-11.66-1.5-23.31.83-34.89,2.14-10.62,7.44-19.17,16.55-25.23.47-.31.95-.8,1.46-.85,1.32-.13,3.12-.59,3.88.07.7.6.76,2.67.31,3.77-2.75,6.65-4.73,13.47-4.68,20.69.07,9.96.37,19.92.78,29.87.11,2.75-.38,4.82-2.46,6.79-4.96,4.69-9.69,9.6-14.52,14.43-.33-.11-.65-.21-.98-.32Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M88.21,199.28c-1.26-6.7-2.62-12.59-3.43-18.56-1.5-11.09-2.92-22.18-1.45-33.45,1.96-15.06,9.4-26.79,21.04-36.14.59-.47,1.27-1.06,1.95-1.12,1.03-.09,2.48-.12,3.06.48.58.6.71,2.19.34,3.04-.54,1.26-1.69,2.25-2.58,3.35-6.9,8.65-9.41,18.68-9.06,29.54.4,12.33.86,24.65,1.44,36.97.15,3.16-.58,5.61-3.07,7.74-2.73,2.33-5.13,5.04-8.23,8.14Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M148.8,138.15c-.2-14.99-2.63-29.64,3.33-43.72,3.29-7.77,8.02-14.41,15.12-19.08,1.53-1.01,3.62-1.17,5.46-1.72-.19,1.77-.07,3.64-.62,5.29-2.16,6.37-3.11,12.88-2.91,19.58.17,5.5.37,11,.36,16.49,0,1.4-.32,3.21-1.21,4.14-5.98,6.22-12.15,12.25-18.27,18.34-.18.18-.46.25-1.27.68Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M204.83,93.39c3.27-3.27,6.06-6.06,8.85-8.85.6-.6,1.2-1.21,1.75-1.86,1.52-1.79,2.06-3.8.32-5.63-1.85-1.95-3.94-1.09-5.55.43-3.63,3.45-7.12,7.06-11.27,11.21-.2-2.41-.55-4.14-.45-5.85.58-10.56,7.82-20.23,17.97-23.33,4.09-1.25,8.51-1.83,12.79-1.95,3.67-.1,5.8,2.3,6.02,5.95,1.03,16.97-11.49,31.48-28.47,30.22-.37-.03-.73-.12-1.97-.34Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M130.07,167.72c3.94-3.94,7.44-7.63,11.2-11.04.77-.7,2.52-.51,3.8-.43,8.05.53,16.09,1.54,24.14,1.6,6.2.05,12.58-.37,18.56-1.86,4.52-1.12,8.53-4.25,12.76-6.52.58-.31,1.02-1.01,1.6-1.12.95-.17,2.26-.36,2.85.13.56.47.82,2.02.47,2.73-.87,1.76-2.02,3.42-3.29,4.93-7.74,9.19-17.88,14.03-29.66,14.07-13.35.05-26.71-1.15-40.06-1.82-.53-.03-1.05-.29-2.36-.68Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M165.06,132.92c5.07-5.07,9.55-9.66,14.19-14.08.75-.72,2.23-.95,3.36-.94,8.71.12,17.42.41,26.13.52,2.36.03,4.72-.41,7.08-.55,3.62-.22,4.97,1.64,3.43,4.97-2.32,5-6.35,8.45-11.49,9.94-4.49,1.3-9.29,2.12-13.95,2.08-8.8-.07-17.6-.9-26.39-1.43-.45-.03-.89-.19-2.36-.52Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M177.41,110.02c-.71-12.98-1.68-25.39,5.45-36.64,2.91-4.59,6.86-8.07,11.55-10.69.84-.47,2.08-.24,3.13-.34-.15,1.03.04,2.29-.49,3.06-6,8.7-7.54,18.22-5.58,28.48.15.8-.04,2.01-.56,2.55-4.26,4.42-8.64,8.73-13.5,13.59Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M113.43,123.38c.11,2.13.2,4.26.32,6.39.77,13.07,1.59,26.13,2.25,39.2.06,1.29-.59,2.9-1.44,3.91-2.06,2.41-4.44,4.55-7.17,7.28-.39-6.36-.88-12-1.04-17.65-.21-7.39-.48-14.81-.11-22.18.2-4.1,1.41-8.2,2.6-12.17.57-1.91,2.15-3.52,3.28-5.27l1.31.49Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M114.65,183.2c2.5-2.5,4.64-4.75,6.92-6.84.54-.49,1.57-.67,2.36-.62,14.21.84,28.41,1.73,42.61,2.64.81.05,1.6.37,3.13.74-1.31,1.31-2.03,2.61-3.07,2.97-4,1.37-8.11,3.48-12.15,3.43-12.79-.15-25.57-1.15-38.35-1.83-.27-.01-.53-.17-1.45-.49Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M188.32,109.66c3.06-3.06,6.08-6.15,9.21-9.13.4-.38,1.42-.34,2.08-.19,9.97,2.33,19.15.5,27.71-5.01,1.97-.91,2.03-.3,3.06-.43-.03,1.03.31,2.26-.13,3.07-3.33,6.01-7.89,10.79-14.85,12.29-8.8,1.9-17.69,1.09-26.54.35-.18-.32-.36-.64-.54-.96Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M67.14,180.11c-.99-6.48-1.09-13.83.72-20.63.29-1.09,1.44-2.72,2.23-2.74,1.28-.03,3.04.75,3.75,1.77.9,1.3,1.24,3.18,1.32,4.83.61,13.11,2.49,26.05,5.11,38.89.18.87.17,1.77.32,3.36-5.17-4.52-8.95-9.14-10.64-15.14" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M196.05,143.46c-5.62,5.61-11.85,7.13-18.41,6.99-8.8-.2-17.59-.94-26.39-1.47-.34-.02-.68-.2-1.84-.55,2.81-2.81,5.2-5.31,7.74-7.65.52-.48,1.59-.54,2.39-.49,10.88.63,21.75,1.28,32.63,2.01,1.17.08,2.31.67,3.89,1.16Z" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M104.14,224.04c-6.55-1.83-12.07-5.17-15.92-10.87,13.35,2.84,26.56,5.15,40.06,5.54,1.61.05,3.35-.33,4.79.18,1.4.5,3.05,1.64,3.6,2.92.79,1.85-.98,2.82-2.58,3.37-6.81,2.31-13.81,2.41-20.78,1.14" style="fill: #b6ade6; stroke-width: 0px;"/>
<path d="M67.24,220.69c2.21-2.21,4.38-4.46,6.64-6.62,2.14-2.04,4.64-2.39,6.06-.79,1.87,2.12.9,4.14-.71,5.8-4.54,4.69-9.14,9.34-13.83,13.89-1.6,1.55-3.67,2.31-5.54.39-1.83-1.88-1.09-3.93.42-5.58,2.23-2.44,4.66-4.71,7-7.06l-.04-.04Z" style="fill: #b6ade6; stroke-width: 0px;"/>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB