Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Capri205 committed May 25, 2023
0 parents commit d937c3a
Show file tree
Hide file tree
Showing 13 changed files with 1,642 additions and 0 deletions.
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# OBAmazeingTimer
No, it's not an amazing timer. It's a rudimentary timer for a maze. In particular, for the awesome maze
on our build server called "A-Maze-Ing".

This plugin will automatically time a players attempt to solve A-Maze-Ing, and update a sign based
leaderboard with the player name, the time and their rank.

Triggers for the start/entry and stop/exit are customizable, along with the maze dimensions for
detecting when a player leaves the maze. The leaderboard is also configurable for placement
and materials, as well as the text color and direction the leaderboard faces.

The elapsed time during a run is displayed in the action bar, as well as the final time as a title
message when you exit the maze by triggering the exit/stop trigger.

Main configuration file contains the start and stop triggers and borders of the maze. The Maze borders
are defined as two corners (so a square maze) and a low and high Y coordinate value. A listener will
detect if you go out of the maze boundary and will cancel the timer, as will leaving the game, getting
killed or warping out etc.

The leaderboard config file contains players and their times. The file contains the times as a hash with
player uuid as the key and their time. This is so we can have one time for a player - uniquness of key.
However, the in-game hash used for the leaderboard is a TreeMap using the time as the key and player as
the value. This is because a TreeMap will automatically add new entries in numeric ascending order, which
is great the for leaderboard as no sorting required and the signs can be rendered directly from the hash.

The signs configuration file contains the sign direction, location, sign and backing materials, as well
as the color of the text on the signs. Title and leaderboard are set separately with a flag for whether
you want to draw the title or not. There is also a setting for the number of sign lines the leaderboard
contains. Each sign line on the leaderboard is a set of 3 horizontally oriented signs which show rank,
player name, and the time. Since a sign has 4 lines, a 3 row leaderboard will have 12 ranks, which is
also the default.

The timer of course can be used for things other than a maze.
Here is my gaudy looking leaderboard showing the title row and 3 leaderboard rows:

![OBAmazeingTimer-leaderboard](https://ob-mc.net/repo/OBAmazeingTimer-leaderboard.png)
![OBAmazeing](https://ob-mc.net/repo/OBAmazeing.png)

You can find A-Maze-Ing in our origial amusement park area at X=634, Z=-85. Join ob-mc.net!

Compiled for 1.19 with Java 17.
77 changes: 77 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>net.obmc</groupId>
<artifactId>OBAmazeingTimer</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>OBAmazeingTimer</name>
<description>Timer for the build server maze called A-Maze-Ing</description>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<build>

<finalName>OBAmazeingTimer</finalName>

<resources>
<resource>
<targetPath>.</targetPath>
<filtering>true</filtering>
<directory>${basedir}/src/main/resources/</directory>
<includes>
<include>*.yml</include>
</includes>
</resource>
</resources>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>

<repositories>
<repository>
<id>spigot repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/public</url>
</repository>
<repository>
<id>jetbrains repo</id>
<url>https://mvnrepository.com/artifact/org.jetbrains/annotations</url>
</repository>
<repository>
<id>apache lang</id>
<url>https://mvnrepository.com/artifact/org.apache.commons/commons-lang3</url>
</repository>
</repositories>

<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.19.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>24.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
</dependencies>

</project>
214 changes: 214 additions & 0 deletions src/main/java/net/obmc/OBAmazeingTimer/EventListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
package net.obmc.OBAmazeingTimer;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.Material;

import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.PlayerDeathEvent;

public class EventListener implements Listener
{
static Logger log = Logger.getLogger("Minecraft");
private String logmsgprefix = null;

public EventListener() {

logmsgprefix = OBAmazeingTimer.getLogMsgPrefix();

}
/*
* Detect a players movement and see if they have triggered a maze timer stop/start event
* Look at the location of the player and see if that matches the triggers from the config
*
* @param {@link PlayerMoveEvent}
*/
@EventHandler
public void onPlayerMove( PlayerMoveEvent event ) {

Player player = event.getPlayer();
Location playerloc = player.getLocation();
MazeTrigger entryloc = OBAmazeingTimer.getInstance().getStartTimerTrigger();
MazeTrigger exitloc = OBAmazeingTimer.getInstance().getStopTimerTrigger();

// Entering maze - only process event if there's no timer running for a player
if ( !OBAmazeingTimer.getInstance().getMazeTimer().timerRunning( player.getUniqueId() ) ) {

// check if we've moved to the entry trigger block
if ((int)playerloc.getX() == entryloc.getPadLocationX() &&
(int)playerloc.getY() == entryloc.getPadLocationY() &&
(int)playerloc.getZ() == entryloc.getPadLocationZ() &&
playerloc.getBlock().getType().equals( entryloc.getPadMaterial() ) ) {

log.log(Level.INFO, logmsgprefix + "Maze entry detected for " + player.getName() + "!" );

// yes, so start a timer and task for the player
OBAmazeingTimer.getInstance().getMazeTimer().StartTimer( player.getUniqueId() );

//TODO: do something?
//player.playSound(player.getLocation(), OBAmazeingTimer.getInstance().getSound(), 1.0f, 1.0f);
//displayEffect(OBAmazeingTimer.getInstance().getEffect(), player.getLocation(), 1.0f, 1.0f, 1.0f, 1.0f, OBAmazeingTimer.getInstance().getParticleCount());
}
}

// Exit maze - checks when a timer is running for a player
if ( OBAmazeingTimer.getInstance().getMazeTimer().timerRunning( player.getUniqueId() ) ) {

// check if we've exited the maze - ignore if not activated
if ((int)playerloc.getX() == exitloc.getPadLocationX() &&
(int)playerloc.getY() == exitloc.getPadLocationY() &&
(int)playerloc.getZ() == exitloc.getPadLocationZ() &&
playerloc.getBlock().getType().equals( exitloc.getPadMaterial() ) ) {

log.log(Level.INFO, logmsgprefix + "Maze exit detected for " + player.getName() + "!" );

OBAmazeingTimer.getInstance().getMazeTimer().StopTimerOnExit( player.getUniqueId() );

//TODO: do sometthing?
//player.playSound(player.getLocation(), OBAmazeingTimer.getInstance().getSound(), 1.0f, 1.0f);
//displayEffect(OBAmazeingTimer.getInstance().getEffect(), player.getLocation(), 1.0f, 1.0f, 1.0f, 1.0f, OBAmazeingTimer.getInstance().getParticleCount());
}

// check if player has somehow moved outside of maze boundaries whilst being timed and cancel timer if they have
// we check the X and Z coordinates of our corners and high and low Y coordinates to form essentially a box
if ((int)playerloc.getX() > (int)OBAmazeingTimer.getInstance().getMazeSideHigh().getX() || (int)playerloc.getX() < (int)OBAmazeingTimer.getInstance().getMazeSideLow().getX() ||
(int)playerloc.getZ() > (int)OBAmazeingTimer.getInstance().getMazeSideHigh().getZ() || (int)playerloc.getZ() < (int)OBAmazeingTimer.getInstance().getMazeSideLow().getZ() ||
(int)playerloc.getY() >= (int)OBAmazeingTimer.getInstance().getMazeHigh() || (int)playerloc.getY() < (int)OBAmazeingTimer.getInstance().getMazeLow()) {

log.log(Level.INFO, logmsgprefix + "Out of boundary detected for " + player.getName() + "!" );

OBAmazeingTimer.getInstance().getMazeTimer().StopTimerOutBounds( player.getUniqueId() );
}
}

}

/**
* See if the player has interacted in some way with our entry or exit place and cancel the event
*
* @param {@link PlayerInteractEvent}
*/
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
Location playerloc = player.getLocation();

MazeTrigger entryloc = OBAmazeingTimer.getInstance().getStartTimerTrigger();
MazeTrigger exitloc = OBAmazeingTimer.getInstance().getStopTimerTrigger();

if ( event.getAction() == Action.PHYSICAL ) {

Material eventplate = event.getClickedBlock().getLocation().getBlock().getType();

// check for entry plate event and cancel event
if (!OBAmazeingTimer.getInstance().getMazeTimer().timerRunning( player.getUniqueId() ) &&
(int)playerloc.getX() == entryloc.getPadLocationX() &&
(int)playerloc.getY() == entryloc.getPadLocationY() &&
(int)playerloc.getZ() == entryloc.getPadLocationZ() &&
eventplate.equals( OBAmazeingTimer.getInstance().getStartTimerTrigger().getPadMaterial() ) ) {
event.setCancelled(true);
}

// check for exit plate event and cancel
if (OBAmazeingTimer.getInstance().getMazeTimer().timerRunning( player.getUniqueId() ) &&
(int)playerloc.getX() == exitloc.getPadLocationX() &&
(int)playerloc.getY() == exitloc.getPadLocationY() &&
(int)playerloc.getZ() == exitloc.getPadLocationZ() &&
eventplate.equals( OBAmazeingTimer.getInstance().getStopTimerTrigger().getPadMaterial() ) ) {
event.setCancelled(true);
}
}
}

@EventHandler
/*
* Detect if a player has quit whilst being timed and cancel their timer and task
*
* @param {@link PlayerQuitEvent}
*/
public void onPlayerQuit( PlayerQuitEvent event ) {

clearTaskTimer( event.getPlayer() );
}

/*
* Detect if a player has been kicked whilst being timed and cancel their timer and task
*
* @param {@link PlayerKickEvent}
*/
@EventHandler
public void onPlayerKick( PlayerKickEvent event ) {

clearTaskTimer( event.getPlayer() );
}

/*
* Detect if a player joins and cancel any tasks that might be left over
*
* @param {@link PlayerJoinEvent}
*/
@EventHandler
public void onPlayerJoin( PlayerJoinEvent event ) {

clearTaskTimer( event.getPlayer() );
}

/*
* Detect if a player respawns and cancel any timers and tasks
*
* @param {@link PlayerRespawnEvent}
*/
@EventHandler
public void onReSpawn( PlayerRespawnEvent event ) {

clearTaskTimer( event.getPlayer() );
}

/*
* Detect if a player leaves the world and cancel any timers and tasks
*
* @param {@link PlayerChangedWorldEvent}
*/
@EventHandler
public void onWorldChange( PlayerChangedWorldEvent event ) {

clearTaskTimer( event.getPlayer() );
}

/*
* Detect if a player dies and cancel any timers and tasks
*
* @param {@link PlayerDeathEvent}
*/
@EventHandler
public void onPlayerDeath( PlayerDeathEvent event ) {

clearTaskTimer( event.getEntity() );
}

/*
* Remove a player timer and cancel any timer tasks
*
* @param {@link Player}
*/
private void clearTaskTimer( Player player ) {

if ( OBAmazeingTimer.getInstance().getMazeTimer().timerRunning( player.getUniqueId() ) ) {

OBAmazeingTimer.getInstance().getMazeTimer().removePlayerTimer( player.getUniqueId() );
OBAmazeingTimer.getInstance().getMazeTimer().removePlayerTask( player.getUniqueId() );
}
}
}
Loading

0 comments on commit d937c3a

Please sign in to comment.