Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
ziqian zhang
Grasscutter
Commits
3585fd59
Commit
3585fd59
authored
Jun 23, 2022
by
Magix
Committed by
GitHub
Jun 23, 2022
Browse files
Merge branch 'development' into plugin-priority
parents
1b58ba25
ed7ffa74
Changes
9
Hide whitespace changes
Inline
Side-by-side
build.gradle
View file @
3585fd59
...
...
@@ -171,13 +171,23 @@ publishing {
}
repositories
{
maven
{
// change URLs to point to your repos, e.g. http://my.org/repo
def
releasesRepoUrl
=
'https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/'
def
snapshotsRepoUrl
=
'https://s01.oss.sonatype.org/content/repositories/snapshots/'
url
=
version
.
endsWith
(
'SNAPSHOT'
)
?
snapshotsRepoUrl
:
releasesRepoUrl
name
=
'sonatype'
credentials
(
PasswordCredentials
)
if
(
version
.
endsWith
(
'-dev'
))
{
println
(
"Publishing to 4benj-maven"
)
url
'https://repo.4benj.com/releases'
name
'4benj-maven'
credentials
{
username
System
.
getenv
(
'benj_maven_username'
)
password
System
.
getenv
(
'benj_maven_token'
)
}
}
else
{
println
(
"Publishing to sonatype"
)
def
releasesRepoUrl
=
'https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/'
def
snapshotsRepoUrl
=
'https://s01.oss.sonatype.org/content/repositories/snapshots/'
url
=
version
.
endsWith
(
'SNAPSHOT'
)
?
snapshotsRepoUrl
:
releasesRepoUrl
name
=
'sonatype'
credentials
(
PasswordCredentials
)
}
}
}
}
...
...
@@ -225,7 +235,9 @@ eclipse {
}
signing
{
sign
publishing
.
publications
.
mavenJava
if
(!
version
.
endsWith
(
'-dev'
))
{
sign
publishing
.
publications
.
mavenJava
}
}
javadoc
{
...
...
src/main/java/emu/grasscutter/auth/ExternalAuthenticator.java
View file @
3585fd59
...
...
@@ -16,18 +16,18 @@ public interface ExternalAuthenticator {
/**
* Called when an external account creation request is made.
* @param request The authentication request.
*
* For developers: Use
{@link
AuthenticationRequest#getRequest()
}
to get the request body.
* Use
{@link
AuthenticationRequest#getResponse()
}
to get the response body.
*
* For developers: Use AuthenticationRequest#getRequest() to get the request body.
* Use AuthenticationRequest#getResponse() to get the response body.
*/
void
handleAccountCreation
(
AuthenticationRequest
request
);
/**
* Called when an external password reset request is made.
* @param request The authentication request.
*
* For developers: Use
{@link
AuthenticationRequest#getRequest()
}
to get the request body.
* Use
{@link
AuthenticationRequest#getResponse()
}
to get the response body.
*
* For developers: Use AuthenticationRequest#getRequest() to get the request body.
* Use AuthenticationRequest#getResponse() to get the response body.
*/
void
handlePasswordReset
(
AuthenticationRequest
request
);
}
src/main/java/emu/grasscutter/scripts/constants/EventType.java
View file @
3585fd59
...
...
@@ -82,4 +82,46 @@ public class EventType {
public
static
final
int
EVENT_SET_GAME_TIME
=
75
;
public
static
final
int
EVENT_HIDE_AND_SEEK_PLAYER_QUIT
=
76
;
public
static
final
int
EVENT_AVATAR_DIE
=
77
;
public
static
final
int
EVENT_SCENE_MULTISTAGE_PLAY_STAGE_START
=
78
;
public
static
final
int
EVENT_GALLERY_PROGRESS_PASS
=
79
;
public
static
final
int
EVENT_GALLERY_PROGRESS_EMPTY
=
80
;
public
static
final
int
EVENT_GALLERY_PROGRESS_FULL
=
81
;
public
static
final
int
EVENT_HUNTING_FINISH_FINAL
=
82
;
public
static
final
int
EVENT_USE_WIDGET_TOY_FOX_CAMERA
=
83
;
public
static
final
int
EVENT_LUNA_RITE_SACRIFICE
=
84
;
public
static
final
int
EVENT_SUMO_SWITCH_TEAM_EVENT
=
85
;
public
static
final
int
EVENT_FISHING_START
=
86
;
public
static
final
int
EVENT_FISHING_STOP
=
87
;
public
static
final
int
EVENT_FISHING_QTE_FINISH
=
88
;
public
static
final
int
EVENT_FISHING_TIMEOUT_FLEE
=
89
;
public
static
final
int
EVENT_ROGUE_CELL_STATE_CHANGE
=
90
;
public
static
final
int
EVENT_ROGUE_CELL_CONSTRUCT
=
91
;
public
static
final
int
EVENT_ROGUE_CELL_FINISH_SELECT_CARD
=
92
;
public
static
final
int
EVENT_ANY_MONSTER_CAPTURE
=
93
;
public
static
final
int
EVENT_ACTIVITY_INTERACT_GADGET
=
94
;
public
static
final
int
EVENT_CHALLENGE_PAUSE
=
95
;
public
static
final
int
EVENT_LEVEL_TAG_CHANGE
=
96
;
public
static
final
int
EVENT_CUSTOM_DUNGEON_START
=
97
;
public
static
final
int
EVENT_CUSTOM_DUNGEON_RESTART
=
98
;
public
static
final
int
EVENT_CUSTOM_DUNGEON_REACTIVE
=
99
;
public
static
final
int
EVENT_CUSTOM_DUNGEON_OUT_STUCK
=
100
;
public
static
final
int
EVENT_CUSTOM_DUNGEON_EXIT_TRY
=
101
;
public
static
final
int
EVENT_CUSTOM_DUNGEON_OFFICIAL_RESTART
=
102
;
public
static
final
int
EVENT_ANY_MONSTER_CAPTURE_AND_DISAPPEAR
=
103
;
public
static
final
int
EVENT_MICHIAE_INTERACT
=
104
;
public
static
final
int
EVENT_SELECT_UIINTERACT
=
105
;
public
static
final
int
EVENT_LUA_NOTIFY
=
106
;
public
static
final
int
EVENT_PHOTO_FINISH
=
107
;
public
static
final
int
EVENT_IRODORI_MASTER_READY
=
108
;
public
static
final
int
EVENT_ROGUE_START_FIGHT
=
109
;
public
static
final
int
EVENT_ROGUE_CREAGE_FIGHT_GADGET
=
110
;
public
static
final
int
EVENT_ROGUE_CREAGE_REPAIR_GADGET
=
111
;
public
static
final
int
EVENT_ROGUE_OPEN_ACCESS
=
112
;
public
static
final
int
EVENT_GADGET_GIVING_FINISHED
=
113
;
public
static
final
int
EVENT_OBSERVATION_POINT_NOTIFY
=
114
;
public
static
final
int
EVENT_GADGET_GIVING_TAKEBACK
=
115
;
public
static
final
int
EVENT_ECHO_SHELL_INTERACT
=
116
;
public
static
final
int
EVENT_PLATFORM_ARRIVAL
=
2701
;
public
static
final
int
EVENT_PLAYER_BACK_GALLERY_REVIVE_POINT
=
2800
;
public
static
final
int
EVENT_GALLERY_CANNOT_START_AFTER_COUNTDOWN
=
2801
;
}
src/main/java/emu/grasscutter/scripts/constants/ScriptRegionShape.java
View file @
3585fd59
...
...
@@ -4,4 +4,6 @@ public class ScriptRegionShape {
public
static
final
int
NONE
=
0
;
public
static
final
int
SPHERE
=
1
;
public
static
final
int
CUBIC
=
2
;
public
static
final
int
CYLINDER
=
3
;
public
static
final
int
POLYGON
=
4
;
}
src/main/java/emu/grasscutter/server/event/game/ServerTickEvent.java
View file @
3585fd59
package
emu.grasscutter.server.event.game
;
import
emu.grasscutter.server.event.types.ServerEvent
;
import
java.time.Instant
;
public
final
class
ServerTickEvent
extends
ServerEvent
{
public
ServerTickEvent
()
{
private
final
Instant
start
,
end
;
public
ServerTickEvent
(
Instant
start
,
Instant
end
)
{
super
(
Type
.
GAME
);
this
.
start
=
start
;
this
.
end
=
end
;
}
public
Instant
getTickStart
()
{
return
this
.
start
;
}
public
Instant
getTickEnd
()
{
return
this
.
end
;
}
}
}
\ No newline at end of file
src/main/java/emu/grasscutter/server/game/GameServer.java
View file @
3585fd59
...
...
@@ -26,11 +26,14 @@ import emu.grasscutter.server.event.types.ServerEvent;
import
emu.grasscutter.server.event.game.ServerTickEvent
;
import
emu.grasscutter.server.event.internal.ServerStartEvent
;
import
emu.grasscutter.server.event.internal.ServerStopEvent
;
import
emu.grasscutter.server.scheduler.ServerTaskScheduler
;
import
emu.grasscutter.task.TaskMap
;
import
kcp.highway.ChannelConfig
;
import
kcp.highway.KcpServer
;
import
lombok.Getter
;
import
java.net.InetSocketAddress
;
import
java.time.Instant
;
import
java.time.OffsetDateTime
;
import
java.util.*
;
import
java.util.concurrent.ConcurrentHashMap
;
...
...
@@ -42,10 +45,11 @@ public final class GameServer extends KcpServer {
private
final
InetSocketAddress
address
;
private
final
GameServerPacketHandler
packetHandler
;
private
final
ServerQuestHandler
questHandler
;
@Getter
private
final
ServerTaskScheduler
scheduler
;
private
final
Map
<
Integer
,
Player
>
players
;
private
final
Set
<
World
>
worlds
;
private
ChatManagerHandler
chatManager
;
private
final
InventoryManager
inventoryManager
;
private
final
GachaManager
gachaManager
;
...
...
@@ -57,14 +61,14 @@ public final class GameServer extends KcpServer {
private
final
TaskMap
taskMap
;
private
final
DropManager
dropManager
;
private
final
WorldDataManager
worldDataManager
;
private
final
CombineManger
combineManger
;
private
final
TowerScheduleManager
towerScheduleManager
;
public
GameServer
()
{
this
(
getAdapterInetSocketAddress
());
}
public
GameServer
(
InetSocketAddress
address
)
{
ChannelConfig
channelConfig
=
new
ChannelConfig
();
channelConfig
.
nodelay
(
true
,
40
,
2
,
true
);
...
...
@@ -80,9 +84,10 @@ public final class GameServer extends KcpServer {
this
.
address
=
address
;
this
.
packetHandler
=
new
GameServerPacketHandler
(
PacketHandler
.
class
);
this
.
questHandler
=
new
ServerQuestHandler
();
this
.
scheduler
=
new
ServerTaskScheduler
();
this
.
players
=
new
ConcurrentHashMap
<>();
this
.
worlds
=
Collections
.
synchronizedSet
(
new
HashSet
<>());
this
.
chatManager
=
new
ChatManager
(
this
);
this
.
inventoryManager
=
new
InventoryManager
(
this
);
this
.
gachaManager
=
new
GachaManager
(
this
);
...
...
@@ -99,7 +104,7 @@ public final class GameServer extends KcpServer {
// Hook into shutdown event.
Runtime
.
getRuntime
().
addShutdownHook
(
new
Thread
(
this
::
onServerShutdown
));
}
public
GameServerPacketHandler
getPacketHandler
()
{
return
packetHandler
;
}
...
...
@@ -119,7 +124,7 @@ public final class GameServer extends KcpServer {
public
ChatManagerHandler
getChatManager
()
{
return
chatManager
;
}
public
void
setChatManager
(
ChatManagerHandler
chatManager
)
{
this
.
chatManager
=
chatManager
;
}
...
...
@@ -131,7 +136,7 @@ public final class GameServer extends KcpServer {
public
GachaManager
getGachaManager
()
{
return
gachaManager
;
}
public
ShopManager
getShopManager
()
{
return
shopManager
;
}
...
...
@@ -143,7 +148,7 @@ public final class GameServer extends KcpServer {
public
DropManager
getDropManager
()
{
return
dropManager
;
}
public
DungeonManager
getDungeonManager
()
{
return
dungeonManager
;
}
...
...
@@ -171,7 +176,7 @@ public final class GameServer extends KcpServer {
public
TaskMap
getTaskMap
()
{
return
this
.
taskMap
;
}
private
static
InetSocketAddress
getAdapterInetSocketAddress
(){
InetSocketAddress
inetSocketAddress
;
if
(
GAME_INFO
.
bindAddress
.
equals
(
""
)){
...
...
@@ -184,7 +189,7 @@ public final class GameServer extends KcpServer {
}
return
inetSocketAddress
;
}
public
void
registerPlayer
(
Player
player
)
{
getPlayers
().
put
(
player
.
getUid
(),
player
);
}
...
...
@@ -192,44 +197,44 @@ public final class GameServer extends KcpServer {
public
Player
getPlayerByUid
(
int
id
)
{
return
this
.
getPlayerByUid
(
id
,
false
);
}
public
Player
getPlayerByUid
(
int
id
,
boolean
allowOfflinePlayers
)
{
// Console check
if
(
id
==
GameConstants
.
SERVER_CONSOLE_UID
)
{
return
null
;
}
// Get from online players
Player
player
=
this
.
getPlayers
().
get
(
id
);
if
(!
allowOfflinePlayers
)
{
return
player
;
}
// Check database if character isnt here
if
(
player
==
null
)
{
player
=
DatabaseHelper
.
getPlayerByUid
(
id
);
}
return
player
;
}
public
Player
getPlayerByAccountId
(
String
accountId
)
{
Optional
<
Player
>
playerOpt
=
getPlayers
().
values
().
stream
().
filter
(
player
->
player
.
getAccount
().
getId
().
equals
(
accountId
)).
findFirst
();
return
playerOpt
.
orElse
(
null
);
}
public
SocialDetail
.
Builder
getSocialDetailByUid
(
int
id
)
{
// Get from online players
Player
player
=
this
.
getPlayerByUid
(
id
,
true
);
if
(
player
==
null
)
{
return
null
;
}
return
player
.
getSocialDetail
();
}
public
Account
getAccountByName
(
String
username
)
{
Optional
<
Player
>
playerOpt
=
getPlayers
().
values
().
stream
().
filter
(
player
->
player
.
getAccount
().
getUsername
().
equals
(
username
)).
findFirst
();
if
(
playerOpt
.
isPresent
())
{
...
...
@@ -238,32 +243,41 @@ public final class GameServer extends KcpServer {
return
DatabaseHelper
.
getAccountByName
(
username
);
}
public
synchronized
void
onTick
(){
Iterator
<
World
>
it
=
this
.
getWorlds
().
iterator
();
while
(
it
.
hasNext
())
{
World
world
=
it
.
next
();
public
synchronized
void
onTick
()
{
var
tickStart
=
Instant
.
now
();
if
(
world
.
getPlayerCount
()
==
0
)
{
it
.
remove
();
}
// Tick worlds.
Iterator
<
World
>
it
=
this
.
getWorlds
().
iterator
();
while
(
it
.
hasNext
())
{
World
world
=
it
.
next
();
world
.
onTick
();
}
if
(
world
.
getPlayerCount
()
==
0
)
{
it
.
remove
();
}
for
(
Player
player
:
this
.
getPlayers
().
values
())
{
player
.
onTick
();
}
world
.
onTick
();
}
// Tick players.
for
(
Player
player
:
this
.
getPlayers
().
values
())
{
player
.
onTick
();
}
// Tick scheduler.
this
.
getScheduler
().
runTasks
();
// Call server tick event.
ServerTickEvent
event
=
new
ServerTickEvent
(
tickStart
,
Instant
.
now
());
event
.
call
();
}
ServerTickEvent
event
=
new
ServerTickEvent
();
event
.
call
();
}
public
void
registerWorld
(
World
world
)
{
this
.
getWorlds
().
add
(
world
);
}
public
void
deregisterWorld
(
World
world
)
{
// TODO Auto-generated method stub
}
public
void
start
()
{
...
...
src/main/java/emu/grasscutter/server/scheduler/AsyncServerTask.java
0 → 100644
View file @
3585fd59
package
emu.grasscutter.server.scheduler
;
import
lombok.Getter
;
import
javax.annotation.Nullable
;
/**
* A server task that should be run asynchronously.
*/
public
final
class
AsyncServerTask
implements
Runnable
{
/* The runnable to run. */
private
final
Runnable
task
;
/* This ID is assigned by the scheduler. */
@Getter
private
final
int
taskId
;
/* The result callback to run. */
@Nullable
private
final
Runnable
callback
;
/* Has the task already been started? */
private
boolean
started
=
false
;
/* Has the task finished execution? */
private
boolean
finished
=
false
;
/* The result produced in the async task. */
@Nullable
private
Object
result
=
null
;
/**
* For tasks without a callback.
* @param task The task to run.
*/
public
AsyncServerTask
(
Runnable
task
,
int
taskId
)
{
this
(
task
,
null
,
taskId
);
}
/**
* For tasks with a callback.
* @param task The task to run.
* @param callback The task to run after the task is complete.
*/
public
AsyncServerTask
(
Runnable
task
,
@Nullable
Runnable
callback
,
int
taskId
)
{
this
.
task
=
task
;
this
.
callback
=
callback
;
this
.
taskId
=
taskId
;
}
/**
* Returns the state of the task.
* @return True if the task has been started, false otherwise.
*/
public
boolean
hasStarted
()
{
return
this
.
started
;
}
/**
* Returns the state of the task.
* @return True if the task has finished execution, false otherwise.
*/
public
boolean
isFinished
()
{
return
this
.
finished
;
}
/**
* Runs the task.
*/
@Override
public
void
run
()
{
// Declare the task as started.
this
.
started
=
true
;
// Run the runnable.
this
.
task
.
run
();
// Declare the task as finished.
this
.
finished
=
true
;
}
/**
* Runs the callback.
*/
public
void
complete
()
{
// Run the callback.
if
(
this
.
callback
!=
null
)
this
.
callback
.
run
();
}
/**
* Sets the result of the async task.
* @param result The result of the async task.
*/
public
void
setResult
(
@Nullable
Object
result
)
{
this
.
result
=
result
;
}
/**
* Returns the set result of the async task.
* @return The result, or null if it has not been set.
*/
@Nullable
public
Object
getResult
()
{
return
this
.
result
;
}
}
src/main/java/emu/grasscutter/server/scheduler/ServerTask.java
0 → 100644
View file @
3585fd59
package
emu.grasscutter.server.scheduler
;
import
emu.grasscutter.Grasscutter
;
import
lombok.*
;
/**
* This class works the same as a runnable, except with more information.
*/
public
final
class
ServerTask
implements
Runnable
{
/* The runnable to run. */
private
final
Runnable
runnable
;
/* This ID is assigned by the scheduler. */
@Getter
private
final
int
taskId
;
/* The period at which the task should be run. */
/* The delay between the first execute. */
private
final
int
period
,
delay
;
public
ServerTask
(
Runnable
runnable
,
int
taskId
,
int
period
,
int
delay
)
{
this
.
runnable
=
runnable
;
this
.
taskId
=
taskId
;
this
.
period
=
period
;
this
.
delay
=
delay
;
}
/* The amount of times the task has been run. */
@Getter
private
int
ticks
=
0
;
/* Should the check consider delay? */
private
boolean
considerDelay
=
true
;
/**
* Cancels the task from running the next time.
*/
public
void
cancel
()
{
Grasscutter
.
getGameServer
().
getScheduler
().
cancelTask
(
this
.
taskId
);
}
/**
* Checks if the task should run at the current tick.
* @return True if the task should run, false otherwise.
*/
public
boolean
shouldRun
()
{
if
(
this
.
delay
!=
-
1
&&
this
.
considerDelay
)
{
this
.
considerDelay
=
false
;
return
this
.
ticks
==
this
.
delay
;
}
else
if
(
this
.
period
!=
-
1
)
return
this
.
ticks
%
this
.
period
==
0
;
else
return
true
;
}
/**
* Checks if the task should be canceled.
* @return True if the task should be canceled, false otherwise.
*/
public
boolean
shouldCancel
()
{
return
this
.
period
==
-
1
;
}
/**
* Runs the task.
*/
@Override
public
void
run
()
{
// Run the runnable.
this
.
runnable
.
run
();
// Increase tick count.
this
.
ticks
++;
}
}
\ No newline at end of file
src/main/java/emu/grasscutter/server/scheduler/ServerTaskScheduler.java
0 → 100644
View file @
3585fd59
package
emu.grasscutter.server.scheduler
;
import
java.util.concurrent.ConcurrentHashMap
;
/**
* A class to manage all time-based tasks scheduled on the server.
* This handles both synchronous and asynchronous tasks.
*
* Developers note: A server tick is ONE REAL-TIME SECOND.
*/
public
final
class
ServerTaskScheduler
{
/* A map to contain all running tasks. */
private
final
ConcurrentHashMap
<
Integer
,
ServerTask
>
tasks
=
new
ConcurrentHashMap
<>();
/* A map to contain all async tasks. */
private
final
ConcurrentHashMap
<
Integer
,
AsyncServerTask
>
asyncTasks
=
new
ConcurrentHashMap
<>();
/* The ID assigned to the next runnable. */
private
int
nextTaskId
=
0
;
/**
* Ran every server tick.
* Attempts to run all scheduled tasks.
* This method is synchronous and will block until all tasks are complete.
*/
public
void
runTasks
()
{
// Skip if there are no tasks.
if
(
this
.
tasks
.
size
()
==
0
)
return
;
// Run all tasks.
for
(
ServerTask
task
:
this
.
tasks
.
values
())
{
// Check if the task should run.
if
(
task
.
shouldRun
())
{
// Run the task.
task
.
run
();
}
// Check if the task should be canceled.
if
(
task
.
shouldCancel
())
{
// Cancel the task.
this
.
cancelTask
(
task
.
getTaskId
());
}
}
// Run all async tasks.
for
(
AsyncServerTask
task
:
this
.
asyncTasks
.
values
())
{
if
(!
task
.
hasStarted
())
{
// Create a thread for the task.
Thread
thread
=
new
Thread
(
task
);
// Start the thread.
thread
.
start
();
}
else
if
(
task
.
isFinished
())
{
// Cancel the task.
this
.
asyncTasks
.
remove
(
task
.
getTaskId
());
// Run the task's callback.
task
.
complete
();
}
}
}
/**
* Gets a task from the scheduler.
* @param taskId The ID of the task to get.
* @return The task, or null if it does not exist.
*/
public
ServerTask
getTask
(
int
taskId
)
{
return
this
.
tasks
.
get
(
taskId
);
}
/**
* Gets an async task from the scheduler.
* @param taskId The ID of the task to get.
* @return The task, or null if it does not exist.
*/
public
AsyncServerTask
getAsyncTask
(
int
taskId
)
{
return
this
.
asyncTasks
.
get
(
taskId
);
}
/**
* Removes a task from the scheduler.
* @param taskId The ID of the task to remove.
*/
public
void
cancelTask
(
int
taskId
)
{
this
.
tasks
.
remove
(
taskId
);
}
/**
* Schedules a task to be run on a separate thread.
* The task runs on the next server tick.
* @param runnable The runnable to run.
* @return The ID of the task.
*/
public
int
scheduleAsyncTask
(
Runnable
runnable
)
{
// Get the next task ID.
var
taskId
=
this
.
nextTaskId
++;
// Create a new task.
this
.
asyncTasks
.
put
(
taskId
,
new
AsyncServerTask
(
runnable
,
taskId
));
// Return the task ID.
return
taskId
;
}
/**
* Schedules a task to be run on the next server tick.
* @param runnable The runnable to run.
* @return The ID of the task.
*/
public
int
scheduleTask
(
Runnable
runnable
)
{
return
this
.
scheduleDelayedRepeatingTask
(
runnable
,
-
1
,
-
1
);
}
/**
* Schedules a task to be run after the amount of ticks has passed.
* @param runnable The runnable to run.
* @param delay The amount of ticks to wait before running.
* @return The ID of the task.
*/
public
int
scheduleDelayedTask
(
Runnable
runnable
,
int
delay
)
{
return
this
.
scheduleDelayedRepeatingTask
(
runnable
,
-
1
,
delay
);
}
/**
* Schedules a task to be run every amount of ticks.
* @param runnable The runnable to run.
* @param period The amount of ticks to wait before running again.
* @return The ID of the task.
*/
public
int
scheduleRepeatingTask
(
Runnable
runnable
,
int
period
)
{
return
this
.
scheduleDelayedRepeatingTask
(
runnable
,
period
,
0
);
}
/**
* Schedules a task to be run after the amount of ticks has passed.
* @param runnable The runnable to run.
* @param period The amount of ticks to wait before running again.
* @param delay The amount of ticks to wait before running the first time.
* @return The ID of the task.
*/
public
int
scheduleDelayedRepeatingTask
(
Runnable
runnable
,
int
period
,
int
delay
)
{
// Get the next task ID.
var
taskId
=
this
.
nextTaskId
++;
// Create a new task.
this
.
tasks
.
put
(
taskId
,
new
ServerTask
(
runnable
,
taskId
,
period
,
delay
));
// Return the task ID.
return
taskId
;
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment