Skip to content

Commit 8f9953b

Browse files
authored
Merge pull request #56 from Tweetzy/dev
merge dev
2 parents 80aa3e1 + 248ba19 commit 8f9953b

File tree

8 files changed

+137
-55
lines changed

8 files changed

+137
-55
lines changed

jitpack.yml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
jdk:
22
- openjdk16
3+
34
before_install:
4-
- echo "Before Install"
5-
- bash ensure-java-16 install
5+
- sdk install java 16.0.1-open
6+
- sdk use java 16.0.1-open
7+
- sdk install maven
8+
- mvn -v
9+
610
install:
7-
- echo "Install"
8-
- if ! bash ensure-java-16 use; then source ~/.sdkman/bin/sdkman-init.sh; fi
9-
- java -version
10-
- mvn install
11+
- mvn install -DskipTests

pom.xml

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,27 @@
77
<artifactId>skulls</artifactId>
88

99
<name>Skulls</name>
10-
<version>3.20.0</version>
10+
<version>3.23.0</version>
1111
<packaging>jar</packaging>
1212

1313
<properties>
1414
<author>Kiran Hart</author>
1515
<jarName>Skulls-${project.version}</jarName>
1616
<main.class>${project.groupId}.${project.artifactId}.${project.name}</main.class>
1717
<java.version>16</java.version>
18-
<flight.version>3.27.1</flight.version>
18+
<flight.version>3.30.0</flight.version>
1919
<flight.path>ca.tweetzy</flight.path>
2020
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
2121
</properties>
2222

23+
<distributionManagement>
24+
<repository>
25+
<id>repsy</id>
26+
<name>Tweetzy Maven Repo On Repsy</name>
27+
<url>https://repo.repsy.io/mvn/kiran/tweetzy</url>
28+
</repository>
29+
</distributionManagement>
30+
2331
<repositories>
2432
<repository>
2533
<id>repsy</id>
@@ -59,7 +67,7 @@
5967
<dependency>
6068
<groupId>org.spigotmc</groupId>
6169
<artifactId>spigot</artifactId>
62-
<version>1.20.4-R0.1-SNAPSHOT</version>
70+
<version>1.21.4-R0.1-SNAPSHOT</version>
6371
<scope>provided</scope>
6472
</dependency>
6573
<dependency>
@@ -186,6 +194,24 @@
186194
</execution>
187195
</executions>
188196
</plugin>
197+
<plugin>
198+
<groupId>com.coderplus.maven.plugins</groupId>
199+
<artifactId>copy-rename-maven-plugin</artifactId>
200+
<version>1.0.1</version>
201+
<executions>
202+
<execution>
203+
<id>copy-named-jar</id>
204+
<phase>package</phase>
205+
<goals>
206+
<goal>copy</goal>
207+
</goals>
208+
<configuration>
209+
<sourceFile>${project.build.directory}/${jarName}.jar</sourceFile>
210+
<destinationFile>D:\Development\Spigot Plugins\Ready Jars\${project.name}\${project.name} - v${project.version}.jar</destinationFile>
211+
</configuration>
212+
</execution>
213+
</executions>
214+
</plugin>
189215
</plugins>
190216
<resources>
191217
<resource>

src/main/java/ca/tweetzy/skulls/guis/MainGUI.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import ca.tweetzy.skulls.Skulls;
2828
import ca.tweetzy.skulls.api.enums.BaseCategory;
2929
import ca.tweetzy.skulls.api.enums.ViewMode;
30+
import ca.tweetzy.skulls.api.interfaces.Skull;
3031
import ca.tweetzy.skulls.guis.abstraction.SkullsBaseGUI;
3132
import ca.tweetzy.skulls.model.SkullItem;
3233
import ca.tweetzy.skulls.model.StringHelper;
@@ -115,6 +116,34 @@ public boolean onResult(String string) {
115116
click.manager.showGUI(click.player, new PlayerHeadGUI(this, Skulls.getPlayerManager().findOrCreate(click.player)));
116117
});
117118

119+
if (Settings.RANDOM_HEAD_BUTTON_ENABLED.getBoolean())
120+
setButton(Settings.GUI_MAIN_ITEMS_RANDOM_HEAD_SLOT.getInt(), QuickItem.of(SkullItem.get("skulls:5171"))
121+
.name(TranslationManager.string(Translations.GUI_MAIN_ITEMS_RANDOM_HEAD_NAME))
122+
.lore(TranslationManager.list(Translations.GUI_MAIN_ITEMS_RANDOM_HEAD_LORE, "price", String.format("%,.2f", Settings.RANDOM_HEAD_BUTTON_PRICE.getDouble())))
123+
.make(), click -> {
124+
125+
if (!Skulls.getPlayerManager().playerCanClaim(player)) {
126+
return;
127+
}
128+
129+
final double price = player.hasPermission("skulls.freeskulls") ? 0 : Settings.RANDOM_HEAD_BUTTON_PRICE.getDouble();
130+
final Skull skull = Skulls.getSkullManager().getRandomAllowedSkull(click.player);
131+
132+
if (price <= 0) {
133+
player.getInventory().addItem(skull.getItemStack());
134+
Common.tell(player, TranslationManager.string(Translations.RECEIVED_RANDOM_SKULL, "skull_name", skull.getName())); return;
135+
}
136+
137+
if (!Skulls.getEconomyManager().has(player, price)) {
138+
Common.tell(player, TranslationManager.string(Translations.NO_MONEY));
139+
return;
140+
}
141+
142+
Skulls.getEconomyManager().withdraw(player, price);
143+
player.getInventory().addItem(skull.getItemStack());
144+
Common.tell(player, TranslationManager.string(Translations.RECEIVED_RANDOM_SKULL, "skull_name", skull.getName()));
145+
});
146+
118147
setButton(Settings.GUI_MAIN_ITEMS_FAVOURITES_SLOT.getInt(), QuickItem.of(SkullItem.get("skulls:39696"))
119148
.name(TranslationManager.string(Translations.GUI_MAIN_ITEMS_FAVOURITES_NAME))
120149
.lore(TranslationManager.list(Translations.GUI_MAIN_ITEMS_FAVOURITES_LORE))

src/main/java/ca/tweetzy/skulls/guis/SettingsGUI.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ protected void draw() {
4646
setButton(1, 2, QuickItem.of(CompMaterial.GOLD_NUGGET).name("&e&lForce Sync Prices").lore("&7Clicking this will force update all the prices", "&7for all skulls to the default category price", "&7set within the configuration file.").make(), click -> {
4747
AtomicInteger total = new AtomicInteger(0);
4848

49-
Skulls.getSkullManager().getSkulls().forEach(skull -> {
49+
Skulls.getSkullManager().getSkulls().values().forEach(skull -> {
5050
final BaseCategory category = BaseCategory.getById(skull.getCategory());
5151
if (skull.getPrice() != category.getDefaultPrice()) {
5252
skull.setPrice(category.getDefaultPrice());

src/main/java/ca/tweetzy/skulls/guis/SkullsViewGUI.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public SkullsViewGUI(final Gui parent, final SkullUser skullPlayer, final String
5656
Bukkit.getPlayer(skullPlayer.getUUID()),
5757
viewMode == ViewMode.SEARCH ? TranslationManager.string(Translations.GUI_SKULLS_LIST_TITLE_SEARCH, "search_phrase", category) : viewMode == ViewMode.FAVOURITE ? TranslationManager.string(Translations.GUI_SKULLS_LIST_TITLE_FAVOURITES) : TranslationManager.string(Translations.GUI_SKULLS_LIST_TITLE_CATEGORY, "category_name", category),
5858
6,
59-
viewMode == ViewMode.SEARCH ? new ArrayList<>() : viewMode == ViewMode.FAVOURITE ? Skulls.getSkullManager().getSkulls(skullPlayer.getFavourites()) : Skulls.getSkullManager().getSkulls(category)
59+
new ArrayList<>()
6060
);
6161

6262
this.category = category;
@@ -70,6 +70,11 @@ public SkullsViewGUI(final Gui parent, final SkullUser skullPlayer, final String
7070
protected void prePopulate() {
7171
if (this.viewMode == ViewMode.SEARCH)
7272
this.items = Skulls.getSkullManager().getSkullsBySearch(this.player, category);
73+
74+
else if (viewMode == ViewMode.FAVOURITE)
75+
this.items = Skulls.getSkullManager().getSkulls(skullPlayer.getFavourites());
76+
else
77+
this.items= Skulls.getSkullManager().getSkulls(category);
7378
}
7479

7580
@Override

src/main/java/ca/tweetzy/skulls/manager/SkullManager.java

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import lombok.Setter;
3636
import org.apache.commons.lang.math.NumberUtils;
3737
import org.bukkit.Bukkit;
38+
import org.bukkit.ChatColor;
3839
import org.bukkit.Location;
3940
import org.bukkit.OfflinePlayer;
4041
import org.bukkit.entity.Player;
@@ -71,10 +72,10 @@ public final class SkullManager implements Manager {
7172
private boolean loading = false;
7273

7374
@Getter
74-
private final List<Skull> skulls = Collections.synchronizedList(new ArrayList<>());
75+
private final ConcurrentHashMap<Integer, Skull> skulls = new ConcurrentHashMap<>();
7576

7677
@Getter
77-
private final List<Integer> idList = Collections.synchronizedList(new ArrayList<>());
78+
private final Set<Integer> idList = Collections.synchronizedSet(new HashSet<>());
7879

7980
@Getter
8081
private final Map<Location, PlacedSkull> placedSkulls = new ConcurrentHashMap<>();
@@ -90,58 +91,61 @@ public List<OfflinePlayer> getOnlineOfflinePlayers() {
9091
}
9192

9293
public Skull getSkull(final int id) {
93-
synchronized (this.skulls) {
94-
return this.skulls.stream().filter(skull -> skull.getId() == id).findFirst().orElse(null);
95-
}
94+
return this.skulls.getOrDefault(id, null);
9695
}
9796

9897
public List<Skull> getSkulls(BaseCategory category) {
99-
synchronized (this.skulls) {
100-
return this.skulls.stream().filter(skull -> skull.getCategory().equalsIgnoreCase(category.getId())).collect(Collectors.toList());
101-
}
98+
return this.skulls.values().stream().filter(skull -> skull.getCategory().equalsIgnoreCase(category.getId())).collect(Collectors.toList());
10299
}
103100

104101
public List<Skull> getSkulls(String category) {
105-
synchronized (this.skulls) {
106-
if (BaseCategory.getById(category) != null)
102+
if (BaseCategory.getById(category) != null)
107103

108-
return this.skulls.stream().filter(skull -> skull.getCategory().equalsIgnoreCase(category)).collect(Collectors.toList());
104+
return this.skulls.values().stream().filter(skull -> skull.getCategory().equalsIgnoreCase(category)).collect(Collectors.toList());
109105

110-
return this.skulls.stream().filter(skull -> Skulls.getCategoryManager().findCategory(category).getSkulls().contains(skull.getId())).collect(Collectors.toList());
111-
}
106+
return this.skulls.values().stream().filter(skull -> Skulls.getCategoryManager().findCategory(category).getSkulls().contains(skull.getId())).collect(Collectors.toList());
112107
}
113108

114109
public Skull getRandomSkull() {
115-
final List<Skull> enabledSkulls = getSkulls().stream().filter(skull -> BaseCategory.getById(skull.getCategory()).isEnabled()).collect(Collectors.toList());
110+
final List<Skull> enabledSkulls = getSkulls().values().stream().filter(skull -> BaseCategory.getById(skull.getCategory()).isEnabled()).toList();
116111
return enabledSkulls.get(random.nextInt(enabledSkulls.size()));
117112
}
118113

119-
public List<Skull> getSkullsBySearch(Player player, String phrase) {
120-
synchronized (this.skulls) {
121-
int id = -1;
122-
if (phrase.startsWith("id:")) {
123-
if (NumberUtils.isNumber(phrase.split(":")[1])) {
124-
id = Integer.parseInt(phrase.split(":")[1]);
125-
}
126-
}
114+
public Skull getRandomAllowedSkull(Player player) {
115+
final List<Skull> enabledSkulls = getSkulls().values().stream().filter(skull -> player.hasPermission("skulls.category." + BaseCategory.getById(skull.getCategory()).getId().toLowerCase().replace(" ", "").replace("&", "")) && BaseCategory.getById(skull.getCategory()).isEnabled() && !skull.isBlocked()).toList();
116+
return enabledSkulls.get(random.nextInt(enabledSkulls.size()));
117+
}
127118

128-
if (id != -1)
129-
return Collections.singletonList(getSkull(id));
119+
public List<Skull> getSkullsBySearch(Player player, String phraseOriginal) {
120+
String phrase = ChatColor.stripColor(phraseOriginal);
130121

131-
return this.skulls.stream().filter(skull -> player.hasPermission("skulls.category." + BaseCategory.getById(skull.getCategory()).getId().toLowerCase().replace(" ", "").replace("&", "")) && BaseCategory.getById(skull.getCategory()).isEnabled() && (Common.match(phrase, skull.getName()) || Common.match(phrase, skull.getCategory()) || skull.getTags().stream().anyMatch(tag -> Common.match(phrase, tag)))).collect(Collectors.toList());
122+
int id = -1;
123+
if (phrase.startsWith("id:")) {
124+
if (NumberUtils.isNumber(phrase.split(":")[1])) {
125+
id = Integer.parseInt(phrase.split(":")[1]);
126+
}
132127
}
128+
129+
if (id != -1)
130+
return Collections.singletonList(getSkull(id));
131+
132+
return this.skulls.values().stream().filter(skull -> player.hasPermission("skulls.category." + BaseCategory.getById(skull.getCategory()).getId().toLowerCase().replace(" ", "").replace("&", "")) && BaseCategory.getById(skull.getCategory()).isEnabled() && (Common.match(phrase, skull.getName()) || Common.match(phrase, skull.getCategory()) || skull.getTags().stream().anyMatch(tag -> Common.match(phrase, tag)))).collect(Collectors.toList());
133133
}
134134

135135
public List<Skull> getSkulls(List<Integer> ids) {
136-
synchronized (this.skulls) {
137-
return this.skulls.stream().filter(skull -> ids.contains(skull.getId())).collect(Collectors.toList());
136+
final List<Skull> results = new ArrayList<>();
137+
138+
for (Integer id : ids) {
139+
final Skull found = this.skulls.getOrDefault(id, null);
140+
if (found != null)
141+
results.add(found);
138142
}
143+
144+
return results;
139145
}
140146

141147
public long getSkullCount(String category) {
142-
synchronized (this.skulls) {
143-
return this.skulls.stream().filter(skull -> skull.getCategory().equalsIgnoreCase(category)).count();
144-
}
148+
return this.skulls.values().stream().filter(skull -> skull.getCategory().equalsIgnoreCase(category)).count();
145149
}
146150

147151
public ItemStack getSkullItem(final int id) {
@@ -171,22 +175,25 @@ public void removePlacedSkull(@NonNull final PlacedSkull placedSkull) {
171175

172176
private void checkAndFixDatabase() {
173177
Bukkit.getServer().getScheduler().runTaskAsynchronously(Skulls.getInstance(), () -> {
174-
final Set<Skull> heads = new HashSet<>();
178+
final Map<Integer, Skull> heads = new HashMap<>();
175179

176180
Common.log("&r&aRunning database check :)");
177181

178182
final List<Skull> downloaded = performHeadDownload(true);
179183
downloaded.forEach(skull -> {
180-
if (this.skulls.contains(skull)) return;
181-
heads.add(skull);
184+
if (!this.skulls.containsKey(skull.getId()))
185+
heads.put(skull.getId(),skull);
182186
});
183187

184-
if (this.skulls.size() < heads.size()) {
185-
Common.log("&r&eFound some missing heads, downloading/inserting them now!");
188+
int oldSize = this.skulls.size();
189+
this.skulls.putAll(heads);
190+
int newSize = this.skulls.size();
186191

187-
this.skulls.addAll(heads);
188-
this.idList.addAll(heads.stream().map(Skull::getId).toList());
189-
Skulls.getDataManager().insertSkulls(new ArrayList<>(heads));
192+
if (newSize > oldSize) {
193+
Skulls.getDataManager().insertSkulls(new ArrayList<>(heads.values()));
194+
Common.log("&r&eFound some new skulls, saving them now :D");
195+
} else {
196+
Common.log("&r&aEverything looks up-to-date, no issues found. Enjoy!");
190197
}
191198
});
192199
}
@@ -198,8 +205,8 @@ public void downloadHeads() {
198205

199206
final List<Skull> heads = new ArrayList<>(performHeadDownload(false));
200207

201-
this.skulls.addAll(heads);
202-
this.idList.addAll(heads.stream().map(Skull::getId).toList());
208+
heads.forEach(skull -> this.skulls.putIfAbsent(skull.getId(), skull));
209+
// this.idList.addAll(heads.stream().map(Skull::getId).toList());
203210
Skulls.getDataManager().insertSkulls(heads);
204211
});
205212
}
@@ -277,8 +284,8 @@ public void load() {
277284
return;
278285
}
279286

280-
this.skulls.addAll(all);
281-
this.idList.addAll(all.stream().map(Skull::getId).toList());
287+
all.forEach(skull -> this.skulls.put(skull.getId(), skull));
288+
// this.idList.addAll(all.stream().map(Skull::getId).toList());
282289

283290
if (this.skulls.isEmpty()) {
284291
Common.log("&cCould not find any skulls, attempting to redownload them!");

src/main/java/ca/tweetzy/skulls/settings/Settings.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ public final class Settings extends FlightSettings {
4444
public static final ConfigEntry GENERAL_USAGE_REQUIRES_NO_PERM = create("general usage requires no permission", false, "If true, no permission is required to use except for admin stuff");
4545
public static final ConfigEntry TELL_OP_PATREON_LINK = create("tell ops patron on join", true);
4646
public static final ConfigEntry SKULL_TRACKING = create("track skull placement", true, "If disabled skulls will no longer drop in creative");
47+
public static final ConfigEntry RANDOM_HEAD_BUTTON_ENABLED = create("random head button.enabled", false, "If enabled players can click to receive a random head (only from categories they have access too)");
48+
public static final ConfigEntry RANDOM_HEAD_BUTTON_PRICE = create("random head button.price", 1.0, "The price for using the random head button");
4749

4850
public static final ConfigEntry CATEGORIES_ALPHABET_ENABLED = create("enabled categories.alphabet", true);
4951
public static final ConfigEntry CATEGORIES_ANIMALS_ENABLED = create("enabled categories.animals", true);
@@ -57,6 +59,7 @@ public final class Settings extends FlightSettings {
5759
public static final ConfigEntry CATEGORIES_PLANTS_ENABLED = create("enabled categories.plants", true);
5860
public static final ConfigEntry CATEGORIES_PLAYER_HEADS_ENABLED = create("enabled categories.player heads", false);
5961

62+
6063
public static final ConfigEntry PLAYER_HEAD_NAME = create("player head.name", "&e%player_name%");
6164
public static final ConfigEntry PLAYER_HEAD_DROP = create("player head.drop enabled", true);
6265
public static final ConfigEntry PLAYER_HEAD_DROP_CHANCE = create("player head.drop chance", 50);
@@ -79,7 +82,7 @@ public final class Settings extends FlightSettings {
7982
public static final ConfigEntry GUI_MAIN_ITEMS_SEARCH_SLOT = create("gui.main.items.search.slot", 41, "-1 to disable it");
8083
public static final ConfigEntry GUI_MAIN_ITEMS_CUSTOM_CATEGORIES_SLOT = create("gui.main.items.custom categories.slot", 38, "-1 to disable it");
8184
public static final ConfigEntry GUI_MAIN_ITEMS_PLAYER_HEADS_SLOT = create("gui.main.items.player heads.slot", 39, "-1 to disable it");
82-
85+
public static final ConfigEntry GUI_MAIN_ITEMS_RANDOM_HEAD_SLOT = create("gui.main.items.random head.slot", 40, "-1 to disable or turn off completely under 'random head button'");
8386

8487
public static final ConfigEntry GUI_MAIN_ITEMS_ALPHABET_SLOT = create("gui.main.items.alphabet.slot", 11);
8588
public static final ConfigEntry GUI_MAIN_ITEMS_ANIMALS_SLOT = create("gui.main.items.animals.slot", 12);

src/main/java/ca/tweetzy/skulls/settings/Translations.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ public Translations(@NonNull JavaPlugin plugin) {
4040
public static final TranslationEntry NO_SKULL_INFO = create("misc.no skull info", "&cCould not determine ID of that skull");
4141
public static final TranslationEntry SKULL_TITLE = create("skull.name", "&e%skull_name%");
4242
public static final TranslationEntry ID_TAKEN = create("misc.id taken", "&cThat category id is already in use!");
43-
public static final TranslationEntry LOADING = create("misc.loading", "&cPlease wait a bit longer, still loading heads.");
4443
public static final TranslationEntry CLAIM_DELAY = create("misc.claim delay", "&cYou can claim another head in &7(&e%time_difference%&7)");
44+
public static final TranslationEntry RECEIVED_RANDOM_SKULL = create("misc.received random skull", "&aYou received a random skull &F(&E%skull_name%&f)");
4545

4646

4747
public static final TranslationEntry ALPHABET = create("categories.alphabet", "Alphabet");
@@ -174,6 +174,17 @@ public Translations(@NonNull JavaPlugin plugin) {
174174
"&e&lClick &8» &7To view your favourites"
175175
);
176176

177+
public static final TranslationEntry GUI_MAIN_ITEMS_RANDOM_HEAD_NAME = create("gui.main.items.random head.name", "<GRADIENT:DD5E89>&lRandom Head</GRADIENT:fbc7d4>");
178+
179+
public static final TranslationEntry GUI_MAIN_ITEMS_RANDOM_HEAD_LORE = create("gui.main.items.random head.lore",
180+
"&7Used to receive a random head from",
181+
"&7a random category that you have access too.",
182+
"",
183+
"&7Cost: &a$%price%",
184+
"",
185+
"&e&lClick &8» &7To receive a random head"
186+
);
187+
177188
public static final TranslationEntry GUI_MAIN_ITEMS_SEARCH_NAME = create("gui.main.items.search.name", "<GRADIENT:DD5E89>&lSearch</GRADIENT:fbc7d4>");
178189

179190
public static final TranslationEntry GUI_MAIN_ITEMS_SEARCH_LORE = create("gui.main.items.search.lore",

0 commit comments

Comments
 (0)