Skip to content

Commit

Permalink
spawning and deathbans
Browse files Browse the repository at this point in the history
  • Loading branch information
UhMarco committed Jun 13, 2023
1 parent c3aeb9f commit 5f5d78f
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,31 @@

import com.marco.simplecivilisations.commands.CivilisationsCommand;
import com.marco.simplecivilisations.commands.OfflineTeleportCommand;
import com.marco.simplecivilisations.commands.ReviveCommand;
import com.marco.simplecivilisations.commands.SeenCommand;
import com.marco.simplecivilisations.listeners.PlayerRespawnEvent;
import com.marco.simplecivilisations.listeners.PlayerJoinListener;
import com.marco.simplecivilisations.listeners.PlayerKickListener;
import com.marco.simplecivilisations.listeners.PlayerQuitListener;
import com.marco.simplecivilisations.sql.MySQL;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;

import java.sql.SQLException;
import java.util.UUID;
import java.util.*;

// Yes, this is the British spelling.
public final class SimpleCivilisations extends JavaPlugin {
private MySQL SQL;

public static ChatColor color = ChatColor.GOLD;
public static final ChatColor color = ChatColor.GOLD;
// I'll stick with color but only because it's forced on me.

public List<Location> spawns = new ArrayList<>();


@Override
public void onEnable() {
// Get these from config file at some point.
Expand All @@ -38,19 +43,26 @@ public void onEnable() {
SQL.connect();
SQL.createTables();
} catch (ClassNotFoundException | SQLException e) {
getLogger().info("Required database not connected. This plugin will not work!");
getLogger().severe("Required database not connected. This plugin will not work!");
Bukkit.getPluginManager().disablePlugin(this);
}

if (SQL.isConnected()) getLogger().info("Database connected.");

getCommand("civilisations").setExecutor(new CivilisationsCommand(this));
getCommand("seen").setExecutor(new SeenCommand(this));
getCommand("offlinetp").setExecutor(new OfflineTeleportCommand(this));
Objects.requireNonNull(getCommand("civilisations")).setExecutor(new CivilisationsCommand(this));
Objects.requireNonNull(getCommand("revive")).setExecutor(new ReviveCommand(this));
Objects.requireNonNull(getCommand("seen")).setExecutor(new SeenCommand(this));
Objects.requireNonNull(getCommand("offlinetp")).setExecutor(new OfflineTeleportCommand(this));


Bukkit.getPluginManager().registerEvents(new PlayerJoinListener(this), this);
Bukkit.getPluginManager().registerEvents(new PlayerQuitListener(this), this);
Bukkit.getPluginManager().registerEvents(new PlayerKickListener(this), this);
Bukkit.getPluginManager().registerEvents(new PlayerRespawnEvent(this), this);

getLogger().info("Calculating spawns (faster on preloaded worlds)...");
generateSpawns(20);
getLogger().info("Spawns calculated.");
}

@Override
Expand All @@ -74,4 +86,31 @@ public static UUID uuidFromName(String name) {
}
return null;
}

public void generateSpawns(int t) {
Random r = new Random();
// TODO: Get these from config
World world = Bukkit.getWorld("world");
assert world != null;
int maxX = 4000;
int minX = 0;
int maxZ = 4000;
int minZ = 0;
for (int i = 0; i < t; i++) {
int x = r.nextInt(minX, maxX);
int z = r.nextInt(minZ, maxZ);
Block block = world.getHighestBlockAt(x, z);
Location l = new Location(world, x + 0.5, block.getY() + 1, z + 0.5);
if (isValid(block)) spawns.add(l);
else i -= 1;
}
}

private boolean isValid(Block block) {
if (block.isEmpty() || block.isLiquid()) return false;
if (block.getType().toString().endsWith("LEAVES")) return false;
//noinspection RedundantIfStatement
if (List.of(Material.CACTUS, Material.MAGMA_BLOCK, Material.SWEET_BERRY_BUSH, Material.POWDER_SNOW).contains(block.getType())) return false;
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.marco.simplecivilisations.commands;

import com.marco.simplecivilisations.SimpleCivilisations;
import com.marco.simplecivilisations.sql.User;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;

import java.util.Collections;
import java.util.List;
import java.util.UUID;

public class ReviveCommand implements TabExecutor {
private final SimpleCivilisations plugin;
public ReviveCommand(SimpleCivilisations plugin) {
this.plugin = plugin;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length == 0) {
sender.sendMessage(ChatColor.RED + "Missing argument.");
return true;
}

UUID uuid = SimpleCivilisations.uuidFromName(args[0]);
if (uuid == null) {
sender.sendMessage(ChatColor.RED + "No player found.");
return true;
}

Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
User user = plugin.getSQL().getUser(uuid);
if (user == null) {
sender.sendMessage(ChatColor.RED + "No user found.");
return;
}
user.setLastDeath(null);
sender.sendMessage("Done.");
});

return true;
}

@Override
public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) {
return Collections.emptyList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public List<String> onTabComplete(CommandSender sender, Command command, String
return Collections.emptyList();
}

private String getTimestampDifference(Timestamp timestamp1, Timestamp timestamp2) {
public static String getTimestampDifference(Timestamp timestamp1, Timestamp timestamp2) {
Duration duration = Duration.between(timestamp1.toInstant(), timestamp2.toInstant());

long years = duration.toDays() / 365;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.marco.simplecivilisations.listeners;

import com.marco.simplecivilisations.SimpleCivilisations;
import org.bukkit.event.Listener;

public abstract class EventListener implements Listener {
protected final SimpleCivilisations plugin;

public EventListener(SimpleCivilisations plugin) {
this.plugin = plugin;
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,33 @@
package com.marco.simplecivilisations.listeners;

import com.marco.simplecivilisations.SimpleCivilisations;
import com.marco.simplecivilisations.commands.SeenCommand;
import com.marco.simplecivilisations.sql.User;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;

public class PlayerJoinListener implements Listener {
private final SimpleCivilisations plugin;
import java.sql.Timestamp;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.TimeUnit;

public class PlayerJoinListener extends EventListener {
public PlayerJoinListener(SimpleCivilisations plugin) {
this.plugin = plugin;
super(plugin);
}

@EventHandler
public void listen(PlayerJoinEvent event) {
plugin.getSQL().createUser(event.getPlayer());
User user = plugin.getSQL().createUser(event.getPlayer());
if (user.getLastDeath() == null) return;
// TODO: get deathban duration from config.
int minutes = 15;
Duration duration = Duration.between(user.getLastDeath().toInstant(), Instant.now());
if (duration.toMinutes() > minutes) {
user.setLastDeath(null);
} else {
Timestamp timeWhenNotBanned = Timestamp.from(user.getLastDeath().toInstant().plusSeconds(TimeUnit.MINUTES.toSeconds(minutes)));
event.getPlayer().kickPlayer("You are deathbanned for another " + SeenCommand.getTimestampDifference(Timestamp.from(Instant.now()), timeWhenNotBanned) + ".");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.marco.simplecivilisations.listeners;

import com.marco.simplecivilisations.SimpleCivilisations;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerKickEvent;

public class PlayerKickListener extends EventListener {

public PlayerKickListener(SimpleCivilisations plugin) {
super(plugin);
}

@EventHandler
public void listen(PlayerKickEvent event) {
plugin.getSQL().updateSession(event.getPlayer());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@

import com.marco.simplecivilisations.SimpleCivilisations;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;

public class PlayerQuitListener implements Listener {
private final SimpleCivilisations plugin;
public class PlayerQuitListener extends EventListener {

public PlayerQuitListener(SimpleCivilisations plugin) {
this.plugin = plugin;
super(plugin);
}

@EventHandler
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.marco.simplecivilisations.listeners;

import com.marco.simplecivilisations.SimpleCivilisations;
import com.marco.simplecivilisations.sql.User;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;

import java.sql.Timestamp;
import java.time.Instant;

public class PlayerRespawnEvent extends EventListener {
public PlayerRespawnEvent(SimpleCivilisations plugin) {
super(plugin);
}

@EventHandler(priority = EventPriority.MONITOR)
public void listen(org.bukkit.event.player.PlayerRespawnEvent event) {
User user = plugin.getSQL().getUser(event.getPlayer().getUniqueId());
user.setLastDeath(Timestamp.from(Instant.now()));
Location bed = event.getPlayer().getBedSpawnLocation();
event.setRespawnLocation(bed != null ? bed : user.getSpawnPoint());
Bukkit.getScheduler().runTask(plugin, () -> {
event.getPlayer().kickPlayer("You died.");
});
}
}
41 changes: 28 additions & 13 deletions src/main/java/com/marco/simplecivilisations/sql/MySQL.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@

import java.sql.*;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Objects;
import java.util.UUID;
import java.util.*;

public class MySQL {
private final SimpleCivilisations plugin;
Expand Down Expand Up @@ -57,7 +55,7 @@ public Connection getConnection() {
public void createTables() {
Bukkit.getLogger().info("[SimpleCivilisations] Completing setup...");
try {
PreparedStatement ps1 = connection.prepareStatement("CREATE TABLE IF NOT EXISTS users (uuid TEXT, civilisation TEXT, role INT, spawnPoint TEXT, lastSession TIMESTAMP, lastLocation TEXT, PRIMARY KEY (uuid(255)))");
PreparedStatement ps1 = connection.prepareStatement("CREATE TABLE IF NOT EXISTS users (uuid TEXT, civilisation TEXT, role INT, spawnPoint TEXT, lastSession TIMESTAMP, lastLocation TEXT, lives INT, lastDeath TIMESTAMP NULL, PRIMARY KEY (uuid(255)))");
PreparedStatement ps2 = connection.prepareStatement("CREATE TABLE IF NOT EXISTS civilisations (uuid TEXT, name TEXT, description TEXT, leader TEXT, open BOOLEAN, waypoint TEXT, PRIMARY KEY (uuid(255)))");
PreparedStatement ps3 = connection.prepareStatement("CREATE TABLE IF NOT EXISTS territories (civilisation TEXT, location TEXT, PRIMARY KEY (civilisation(255), location(255)))");
PreparedStatement ps4 = connection.prepareStatement("CREATE TABLE IF NOT EXISTS invites (civilisation TEXT, user TEXT, PRIMARY KEY (civilisation(255), user(255)))");
Expand All @@ -83,29 +81,44 @@ public boolean exists(UUID uuid) {
return false;
}

public void createUser(Player player) {
public User createUser(Player player) {
try {
UUID uuid = player.getUniqueId();
if (exists(uuid)) return;
if (exists(uuid)) return getUser(player.getUniqueId());

PreparedStatement ps = connection.prepareStatement("INSERT INTO users (uuid, civilisation, role, spawnPoint, lastSession, lastLocation) VALUES (?, ?, ?, ?, ?, ?)");
PreparedStatement ps = connection.prepareStatement("INSERT INTO users (uuid, civilisation, role, spawnPoint, lastSession, lastLocation, lives, lastDeath) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
ps.setString(1, uuid.toString());
ps.setString(2, null);
ps.setInt(3, 0);

// TODO: Generate a random location and never change it.
ps.setObject(4, serialiseLocation(player.getBedSpawnLocation() != null
? player.getBedSpawnLocation()
: player.getWorld().getSpawnLocation())
);

Location location = plugin.spawns.remove(0);
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> plugin.generateSpawns(1));
ps.setObject(4, serialiseLocation(location));

Bukkit.getScheduler().runTask(plugin, () -> player.teleport(location));

ps.setTimestamp(5, Timestamp.from(Instant.now()));
ps.setString(6, serialiseLocation(player.getLocation()));
ps.setInt(7, 0);
ps.setTimestamp(8, null);

ps.executeUpdate();
return new User(
plugin,
uuid,
null,
0,
player.getWorld().getSpawnLocation(),
Timestamp.from(Instant.now()),
player.getLocation(),
0,
null
);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}

public void updateSession(Player player) {
Expand Down Expand Up @@ -140,7 +153,9 @@ public User getUser(UUID uuid) {
results.getInt("role"),
deserialiseLocation(results.getString("spawnPoint")),
results.getTimestamp("lastSession"),
deserialiseLocation(results.getString("lastLocation"))
deserialiseLocation(results.getString("lastLocation")),
results.getInt("lives"),
results.getTimestamp("lastDeath")
);
} catch (Exception e) {
e.printStackTrace();
Expand Down
Loading

0 comments on commit 5f5d78f

Please sign in to comment.