2022-04-22 19:02:05 +08:00
package emu.grasscutter.command.commands ;
2022-04-23 23:07:18 +08:00
import emu.grasscutter.Grasscutter ;
2022-04-22 19:02:05 +08:00
import emu.grasscutter.command.Command ;
import emu.grasscutter.command.CommandHandler ;
2022-04-25 21:53:10 +08:00
import emu.grasscutter.database.DatabaseHelper ;
2022-04-27 12:24:25 +08:00
import emu.grasscutter.game.mail.Mail ;
import emu.grasscutter.game.player.Player ;
2022-04-22 19:02:05 +08:00
2022-04-25 21:53:10 +08:00
import java.util.HashMap ;
2022-04-22 19:02:05 +08:00
import java.util.List ;
2022-04-25 21:53:10 +08:00
@Command ( label = " sendmail " , usage = " sendmail <userId|all|help> [templateId] " ,
description = " Sends mail to the specified user. The usage of this command changes based on it's composition state. " , permission = " server.sendmail " )
2022-04-29 10:21:30 +08:00
public final class SendMailCommand implements CommandHandler {
2022-04-22 19:02:05 +08:00
2022-04-25 21:53:10 +08:00
// TODO: You should be able to do /sendmail and then just send subsequent messages until you finish
// However, due to the current nature of the command system, I don't think this is possible without rewriting
// the command system (again). For now this will do
// Key = User that is constructing the mail.
2022-04-29 10:21:30 +08:00
private static final HashMap < Integer , MailBuilder > mailBeingConstructed = new HashMap < Integer , MailBuilder > ( ) ;
2022-04-25 21:53:10 +08:00
// Yes this is awful and I hate it.
2022-04-22 19:02:05 +08:00
@Override
2022-04-27 12:21:57 +08:00
public void execute ( Player sender , List < String > args ) {
2022-04-25 21:53:10 +08:00
int senderId ;
if ( sender ! = null ) {
senderId = sender . getUid ( ) ;
} else {
senderId = - 1 ;
}
if ( ! mailBeingConstructed . containsKey ( senderId ) ) {
switch ( args . size ( ) ) {
2022-04-27 09:03:26 +08:00
case 1 - > {
2022-04-25 21:53:10 +08:00
MailBuilder mailBuilder ;
switch ( args . get ( 0 ) . toLowerCase ( ) ) {
2022-04-27 09:03:26 +08:00
case " help " - > {
2022-04-25 21:53:10 +08:00
CommandHandler . sendMessage ( sender , this . getClass ( ) . getAnnotation ( Command . class ) . description ( ) + " \ nUsage: " + this . getClass ( ) . getAnnotation ( Command . class ) . usage ( ) ) ;
return ;
2022-04-27 09:03:26 +08:00
}
case " all " - > mailBuilder = new MailBuilder ( true , new Mail ( ) ) ;
default - > {
2022-04-25 21:53:10 +08:00
if ( DatabaseHelper . getPlayerById ( Integer . parseInt ( args . get ( 0 ) ) ) ! = null ) {
mailBuilder = new MailBuilder ( Integer . parseInt ( args . get ( 0 ) ) , new Mail ( ) ) ;
} else {
CommandHandler . sendMessage ( sender , " The user with an id of ' " + args . get ( 0 ) + " ' does not exist " ) ;
return ;
}
2022-04-27 09:03:26 +08:00
}
2022-04-25 21:53:10 +08:00
}
mailBeingConstructed . put ( senderId , mailBuilder ) ;
CommandHandler . sendMessage ( sender , " Starting composition of message. \ nPlease use `/sendmail <title>` to continue. \ nYou can use `/sendmail stop` at any time " ) ;
2022-04-27 09:03:26 +08:00
}
case 2 - > CommandHandler . sendMessage ( sender , " Mail templates coming soon implemented... " ) ;
default - > CommandHandler . sendMessage ( sender , " Invalid arguments. \ nUsage `/sendmail <userId|all|help> [templateId]` " ) ;
2022-04-25 21:53:10 +08:00
}
} else {
MailBuilder mailBuilder = mailBeingConstructed . get ( senderId ) ;
if ( args . size ( ) > = 1 ) {
switch ( args . get ( 0 ) . toLowerCase ( ) ) {
2022-04-27 09:03:26 +08:00
case " stop " - > {
2022-04-25 21:53:10 +08:00
mailBeingConstructed . remove ( senderId ) ;
CommandHandler . sendMessage ( sender , " Message sending cancelled " ) ;
return ;
2022-04-27 09:03:26 +08:00
}
case " finish " - > {
2022-04-25 21:53:10 +08:00
if ( mailBuilder . constructionStage = = 3 ) {
2022-04-29 10:21:30 +08:00
if ( ! mailBuilder . sendToAll ) {
2022-04-25 21:53:10 +08:00
Grasscutter . getGameServer ( ) . getPlayerByUid ( mailBuilder . recipient , true ) . sendMail ( mailBuilder . mail ) ;
CommandHandler . sendMessage ( sender , " Message sent to user " + mailBuilder . recipient + " ! " ) ;
} else {
2022-04-27 12:21:57 +08:00
for ( Player player : DatabaseHelper . getAllPlayers ( ) ) {
2022-04-26 11:57:55 +08:00
Grasscutter . getGameServer ( ) . getPlayerByUid ( player . getUid ( ) , true ) . sendMail ( mailBuilder . mail ) ;
2022-04-25 21:53:10 +08:00
}
CommandHandler . sendMessage ( sender , " Message sent to all users! " ) ;
}
mailBeingConstructed . remove ( senderId ) ;
} else {
CommandHandler . sendMessage ( sender , " Message composition not at final stage. \ nPlease use `/sendmail " + getConstructionArgs ( mailBuilder . constructionStage ) + " ` or `/sendmail stop` to cancel " ) ;
}
return ;
2022-04-27 09:03:26 +08:00
}
case " help " - > {
2022-04-25 21:53:10 +08:00
CommandHandler . sendMessage ( sender , " Please use `/sendmail " + getConstructionArgs ( mailBuilder . constructionStage ) + " ` " ) ;
return ;
2022-04-27 09:03:26 +08:00
}
default - > {
2022-04-25 21:53:10 +08:00
switch ( mailBuilder . constructionStage ) {
2022-04-27 09:03:26 +08:00
case 0 - > {
2022-04-25 21:53:10 +08:00
String title = String . join ( " " , args . subList ( 0 , args . size ( ) ) ) ;
mailBuilder . mail . mailContent . title = title ;
CommandHandler . sendMessage ( sender , " Message title set as ' " + title + " '. \ nUse '/sendmail <content>' to continue. " ) ;
mailBuilder . constructionStage + + ;
2022-04-27 09:03:26 +08:00
}
case 1 - > {
2022-04-25 21:53:10 +08:00
String contents = String . join ( " " , args . subList ( 0 , args . size ( ) ) ) ;
mailBuilder . mail . mailContent . content = contents ;
CommandHandler . sendMessage ( sender , " Message contents set as ' " + contents + " '. \ nUse '/sendmail <sender>' to continue. " ) ;
mailBuilder . constructionStage + + ;
2022-04-27 09:03:26 +08:00
}
case 2 - > {
2022-04-25 21:53:10 +08:00
String msgSender = String . join ( " " , args . subList ( 0 , args . size ( ) ) ) ;
mailBuilder . mail . mailContent . sender = msgSender ;
CommandHandler . sendMessage ( sender , " Message sender set as ' " + msgSender + " '. \ nUse '/sendmail <itemId|itemName|finish> [amount] [level]' to continue. " ) ;
mailBuilder . constructionStage + + ;
2022-04-27 09:03:26 +08:00
}
case 3 - > {
2022-04-25 21:53:10 +08:00
// Literally just copy-pasted from the give command lol.
int item , lvl , amount = 1 ;
switch ( args . size ( ) ) {
2022-04-27 09:03:26 +08:00
default - > { // *No args*
2022-04-25 21:53:10 +08:00
CommandHandler . sendMessage ( sender , " Usage: give [player] <itemId|itemName> [amount] " ) ;
return ;
2022-04-27 09:03:26 +08:00
}
case 1 - > { // <itemId|itemName>
2022-04-25 21:53:10 +08:00
try {
item = Integer . parseInt ( args . get ( 0 ) ) ;
lvl = 1 ;
} catch ( NumberFormatException ignored ) {
// TODO: Parse from item name using GM Handbook.
CommandHandler . sendMessage ( sender , " Invalid item id. " ) ;
return ;
}
2022-04-27 09:03:26 +08:00
}
case 2 - > { // <itemId|itemName> [amount]
2022-04-25 21:53:10 +08:00
lvl = 1 ;
item = Integer . parseInt ( args . get ( 0 ) ) ;
amount = Integer . parseInt ( args . get ( 1 ) ) ;
2022-04-27 09:03:26 +08:00
}
case 3 - > { // <itemId|itemName> [amount] [level]
2022-04-25 21:53:10 +08:00
try {
item = Integer . parseInt ( args . get ( 0 ) ) ;
amount = Integer . parseInt ( args . get ( 1 ) ) ;
lvl = Integer . parseInt ( args . get ( 2 ) ) ;
} catch ( NumberFormatException ignored ) {
// TODO: Parse from item name using GM Handbook.
CommandHandler . sendMessage ( sender , " Invalid item or player ID. " ) ;
return ;
}
2022-04-27 09:03:26 +08:00
}
2022-04-25 21:53:10 +08:00
}
mailBuilder . mail . itemList . add ( new Mail . MailItem ( item , amount , lvl ) ) ;
CommandHandler . sendMessage ( sender , String . format ( " Attached %s of %s (level %s) to the message. \ nContinue adding more items or use `/sendmail finish` to send the message. " , amount , item , lvl ) ) ;
2022-04-27 09:03:26 +08:00
}
2022-04-25 21:53:10 +08:00
}
2022-04-27 09:03:26 +08:00
}
2022-04-25 21:53:10 +08:00
}
} else {
CommandHandler . sendMessage ( sender , " Invalid arguments \ n Please use `/sendmail " + getConstructionArgs ( mailBuilder . constructionStage ) ) ;
}
}
}
2022-04-27 09:03:26 +08:00
private String getConstructionArgs ( int stage ) {
2022-04-25 21:53:10 +08:00
switch ( stage ) {
2022-04-27 09:03:26 +08:00
case 0 - > {
2022-04-25 21:53:10 +08:00
return " <title> " ;
2022-04-27 09:03:26 +08:00
}
case 1 - > {
2022-04-25 21:53:10 +08:00
return " <message> " ;
2022-04-27 09:03:26 +08:00
}
case 2 - > {
2022-04-25 21:53:10 +08:00
return " <sender> " ;
2022-04-27 09:03:26 +08:00
}
case 3 - > {
2022-04-25 21:53:10 +08:00
return " <itemId|itemName|finish> [amount] [level] " ;
2022-04-27 09:03:26 +08:00
}
default - > {
2022-04-25 21:53:10 +08:00
Thread . dumpStack ( ) ;
return " ERROR: invalid construction stage " + stage + " . Check console for stacktrace. " ;
2022-04-27 09:03:26 +08:00
}
2022-04-23 23:07:18 +08:00
}
2022-04-25 21:53:10 +08:00
}
public static class MailBuilder {
public int recipient ;
public boolean sendToAll ;
public int constructionStage ;
public Mail mail ;
2022-04-23 23:07:18 +08:00
2022-04-25 21:53:10 +08:00
public MailBuilder ( int recipient , Mail mail ) {
this . recipient = recipient ;
this . sendToAll = false ;
this . constructionStage = 0 ;
this . mail = mail ;
}
public MailBuilder ( boolean sendToAll , Mail mail ) {
if ( sendToAll ) {
this . recipient = 0 ;
this . sendToAll = true ;
this . constructionStage = 0 ;
this . mail = mail ;
} else {
Grasscutter . getLogger ( ) . error ( " Please use MailBuilder(int, mail) when not sending to all " ) ;
Thread . dumpStack ( ) ;
}
}
2022-04-22 19:02:05 +08:00
}
}