gpt4 book ai didi

java - Spigot API - 从玩家获取多个字符串

转载 作者:行者123 更新时间:2023-12-01 20:55:38 26 4
gpt4 key购买 nike

我试图做到这一点,当您单击一个标志时,它会显示“输入您的标签”,然后您输入您的标签,然后它会显示“输入您的括号颜色”,然后您输入您的括号颜色,然后输入您的命名颜色,然后聊天颜色。它有效,但有时括号颜色设置名称颜色,一旦我设置聊天颜色,它可能会这样做。谁能告诉我我的代码有什么问题吗?

ArrayList<Player>  input = new ArrayList<Player>();
@EventHandler
public void onChat(AsyncPlayerChatEvent event){
Player p = event.getPlayer();
if(input.contains(p)){
String tag = event.getMessage();
event.setCancelled(true);
if(tag.equals("clear")){
UUID playerid = p.getUniqueId();
FileConfiguration cfg = getTagsConfig();
cfg.set("tags." + playerid + ".tag", null);
p.sendMessage(ChatColor.GREEN + "Tag Cleared!");
}
else{
UUID playerid = p.getUniqueId();
FileConfiguration cfg = getTagsConfig();
cfg.set("tags." + playerid + ".tag", tag);
p.sendMessage(ChatColor.GREEN + "Your prefix is now " + tag);
}
saveTagsFile();
input.remove(p);
p.sendMessage(ChatColor.RED + "Enter a bracket color (lowercase)");
p.sendMessage(ChatColor.GREEN + "a" + ChatColor.AQUA + "b" + ChatColor.RED + "c" + ChatColor.LIGHT_PURPLE + "d" + ChatColor.YELLOW + "e" + ChatColor.WHITE + "f" + ChatColor.DARK_BLUE + "1" + ChatColor.DARK_GREEN + "2" + ChatColor.DARK_AQUA + "3" + ChatColor.DARK_RED + "4" + ChatColor.DARK_PURPLE + "5" + ChatColor.GOLD + "6" + ChatColor.GRAY + "7" + ChatColor.DARK_GRAY + "8" + ChatColor.BLUE + "9" + ChatColor.BLACK + "0");
input2.add(p);
}
}
ArrayList<Player> input2 = new ArrayList<Player>();
@EventHandler
public void onChat2(AsyncPlayerChatEvent event){
Player p = event.getPlayer();
if(input2.contains(p)){
p.sendMessage(ChatColor.RED + "Enter a bracket color (lowercase)");
p.sendMessage(ChatColor.GREEN + "a" + ChatColor.AQUA + "b" + ChatColor.RED + "c" + ChatColor.LIGHT_PURPLE + "d" + ChatColor.YELLOW + "e" + ChatColor.WHITE + "f" + ChatColor.DARK_BLUE + "1" + ChatColor.DARK_GREEN + "2" + ChatColor.DARK_AQUA + "3" + ChatColor.DARK_RED + "4" + ChatColor.DARK_PURPLE + "5" + ChatColor.GOLD + "6" + ChatColor.GRAY + "7" + ChatColor.DARK_GRAY + "8" + ChatColor.BLUE + "9" + ChatColor.BLACK + "0");
String brackets = event.getMessage();
event.setCancelled(true);
if(brackets.equals("a")||brackets.equals("b")||brackets.equals("c")||brackets.equals("d")||brackets.equals("e")||brackets.equals("f")||brackets.equals("1")||brackets.equals("2")||brackets.equals("3")||brackets.equals("4")||brackets.equals("5")||brackets.equals("6")||brackets.equals("7")||brackets.equals("8")||brackets.equals("9")||brackets.equals("0")){
UUID playerid = p.getUniqueId();
FileConfiguration cfg = getTagsConfig();
cfg.set("tags." + playerid + ".brackets", brackets);
p.sendMessage(ChatColor.GREEN + "Bracket color set to: " + "" + brackets);
}
else{
return;
}
saveTagsFile();
input2.remove(p);
p.sendMessage(ChatColor.RED + "Enter a name color (lowercase)");
p.sendMessage(ChatColor.GREEN + "a" + ChatColor.AQUA + "b" + ChatColor.RED + "c" + ChatColor.LIGHT_PURPLE + "d" + ChatColor.YELLOW + "e" + ChatColor.WHITE + "f" + ChatColor.DARK_BLUE + "1" + ChatColor.DARK_GREEN + "2" + ChatColor.DARK_AQUA + "3" + ChatColor.DARK_RED + "4" + ChatColor.DARK_PURPLE + "5" + ChatColor.GOLD + "6" + ChatColor.GRAY + "7" + ChatColor.DARK_GRAY + "8" + ChatColor.BLUE + "9");
input3.add(p);
}
}
ArrayList<Player> input3 = new ArrayList<Player>();
@EventHandler
public void onChat3(AsyncPlayerChatEvent event){
Player p = event.getPlayer();
if(input3.contains(p)){
p.sendMessage(ChatColor.RED + "Enter a name color (lowercase)");
p.sendMessage(ChatColor.GREEN + "a" + ChatColor.AQUA + "b" + ChatColor.RED + "c" + ChatColor.LIGHT_PURPLE + "d" + ChatColor.YELLOW + "e" + ChatColor.WHITE + "f" + ChatColor.DARK_BLUE + "1" + ChatColor.DARK_GREEN + "2" + ChatColor.DARK_AQUA + "3" + ChatColor.DARK_RED + "4" + ChatColor.DARK_PURPLE + "5" + ChatColor.GOLD + "6" + ChatColor.GRAY + "7" + ChatColor.DARK_GRAY + "8" + ChatColor.BLUE + "9");
String name = event.getMessage();
event.setCancelled(true);
if(name.equals("a")||name.equals("b")||name.equals("c")||name.equals("d")||name.equals("e")||name.equals("f")||name.equals("1")||name.equals("2")||name.equals("3")||name.equals("4")||name.equals("5")||name.equals("6")||name.equals("7")||name.equals("8")||name.equals("9")){
UUID playerid = p.getUniqueId();
FileConfiguration cfg = getTagsConfig();
cfg.set("tags." + playerid + ".name", name);
p.sendMessage(ChatColor.GREEN + "Name color set to: " + "" + name);
}
else{
return;
}
saveTagsFile();
input3.remove(p);
}
}

最佳答案

我当然理解您想要完成的任务以及您的“队列”概念(即inputinput2 等)是可靠的。然而,实际控制的实现却让一些人假设不一定成立。

重复提示
正如 MrDarkLynx 已经指出的那样,您正在发送双重提示。幸运的是,这只是外观问题。

事件监听器调用顺序
鉴于您的事件处理程序都具有相同的事件优先级(正常),因此不能保证您它们按照定义的顺序调用(即 onChat()onChat2()onChat3())。

维护事件监听器的

HandlerList 确实使用数组和 ArrayList,但是SimplePluginManager 的监听器注册没有。您的 Activity 顺序可能会改变服务器重新启动之间。调用顺序在服务器 session 期间将保持一致,除非它们在插件管理器中取消注册并重新注册。

取消 Activity
取消事件不会阻止您或其他插件的事件处理程序处理该事件事件。取消仅将事件标记为已取消。您必须明确检查它

if ( event.isCancelled() )
return;

或在事件注释中指定

@EventHandler( ignoreCancelled=true )

DIY解决方案

本质上,您想要实现的是一个管理对话的状态机在您的插件和玩家之间,在此期间系统会提示玩家提供答案,直到完成任务已完成或取消。

DIY 方法是实现一个实际的状态机,其每当玩家导致某些事件发生时就会触发执行。我引用这个解决方案作为DIY,因为有更好的解决方案,我将在下面进一步介绍。

下面的代码是事件处理程序的一个模型,它是一个单一的状态机能够维护多个玩家的状态。请记住,虽然此代码有效,它纯粹用于教育和演示目的。使用风险由您自行承担。

public class DyiTagController implements Listener {
private static final String VALID_COLOR_PAT = "^[a-f0-9]$";

/** Valid controller states*/
private enum TagState {
PREFIX, BRACKET, NAME, DONE, ERR
};

/** Registry of current player sessions */
private final Map<Player, PlayerSession> sessions = new HashMap<>();

/**
* Constructs a DyiTagController and self-registers itself as event listener
*
* @param plugin main plugin reference
*/
public DyiTagController( JavaPlugin plugin ) {
Bukkit.getPluginManager().registerEvents( this, plugin );
}

/**
* Only process un-cancelled chat events. If player has an active state, handle chat
* message as input to be further validated; otherwise, ignore it.
*
* @param event chat event record
*/
@EventHandler( ignoreCancelled = true )
public void onPlayerChat( AsyncPlayerChatEvent event ) {
Player player = event.getPlayer();
if ( sessions.containsKey( event.getPlayer() ) ) {
processResponse( player, event.getMessage() );
event.setCancelled( true );
}
}


/**
* Handle sign interaction to start a dialog.
*
* @param event player interaction record
*/
@EventHandler( ignoreCancelled = true )
public void onPlayerInteract( PlayerInteractEvent event ) {
if ( event.getAction() != Action.RIGHT_CLICK_BLOCK )
return;

Block block = event.getClickedBlock();

if ( block.getType() == Material.WALL_SIGN ) {
// Other tests to make sure its the right sign
startTagController( event.getPlayer() );
}
}


/**
* Trigger the start of a player's conversation. This would be called by your sign
* interaction handler or started by a command.
*
* @param player player for which conversation is to be started
*/
public void startTagController( Player player ) {
if ( sessions.containsKey( player ) )
return; // Already has a controller

PlayerSession sess = new PlayerSession();
sess.state = TagState.PREFIX;
sessions.put( player, sess );
promptPlayer( player );
}


/**
* Display the appropriate prompt to the player depending on what state they are currently
* in.
*
* @param player player in conversation
*/
private void promptPlayer( Player player ) {
String prompt = null;
switch ( sessions.get( player ).state ) {
case PREFIX:
prompt = "Enter a prefix (enter 'clear' to quit)";
break;
case BRACKET:
prompt = "Enter a bracket color";
break;
case NAME:
prompt = "Enter a name color";
break;
default:
cleanup( player );
player.sendMessage( "Sorry some bad has happened, exiting tag manager" );
throw new IllegalStateException( "Unknown tag state" );
}

player.sendMessage( prompt );
}


/**
* Process chat response. Evaluate message and determine next valid state. If next state
* is anything other than DONE, set player's current state to it and prompt them. This will
* also reprompt player should they enter an invalid value.
*
* @param player player responding
* @param msg response message
*/
private void processResponse( Player player, String msg ) {
PlayerSession sess = sessions.get( player );
sess.state = evaluateState( player, sess, msg );

if ( sess.state == TagState.DONE || sess.state == TagState.ERR )
cleanup( player );
else
promptPlayer( player );
}


/**
* Evaluate the given message according to the current state.
*
* @param player player in conversation
* @param state current player state
* @param msg response message to evaluate
* @return next valid state; same state if invalidation errors; or ERR if terminal error.
*/
private TagState evaluateState( Player player, PlayerSession sess, String msg ) {
if ( "clear".equalsIgnoreCase( msg ) )
return TagState.DONE;

switch ( sess.state ) {
case PREFIX:
if ( validatePrefix( msg ) ) {
// Do something with valid prefix
sess.prefix = msg;
return TagState.BRACKET;
}
// Bark error at player, don't change state.
return sess.state;

case BRACKET:
if ( validateColor( msg ) ) {
// Do something with valid bracket color
sess.bracket = msg;
return TagState.NAME;
}
// Bark error at player, don't change state.
return sess.state;

case NAME:
if ( validateColor( msg ) ) {
// Do something with valid name color
sess.name = msg;
return TagState.DONE;
}
// Bark error at player, don't change state.
return sess.state;

default:
player.sendMessage( "Sorry some bad has happened, exiting tag manager" );
return TagState.ERR;
}
}


/**
* Determine if the given prefix is valid.
*
* @param prefix prefix to evaluate
* @return true if valid; false otherwise.
*/
private boolean validatePrefix( String prefix ) {
// Check whether prefix is valid. Return true if it is and false if not
return true;
}


/**
* Determine if the given color key is valid.
*
* @param color color key to evaluate
* @return true if valid; false otherwise.
*/
private boolean validateColor( String color ) {
return color.matches( VALID_COLOR_PAT );
}


/**
* Clean up after given player has completed or terminated conversation.
*
* @param player conversation player
*/
private void cleanup( Player player ) {
PlayerSession sess = sessions.get( player );
sessions.remove( player );

if ( sess.state == TagState.DONE ) {
player.sendMessage( "Prefix selected: " + sess.prefix );
player.sendMessage( "Bracket color selected: " + sess.bracket );
player.sendMessage( "Name color selected: " + sess.name );
}
}

protected class PlayerSession {
public TagState state;
public String prefix;
public String bracket;
public String name;
}
}

Bukkit 对话

Bukkit 的一个罕见功能,除非有人指出或仔细阅读 Bukkit 的内容,否则很多人都不会发现源代码是其 org.bukkit.conversations.ConversationFactory 资源。它是一个框架,专门用于您想要实现的目标。它有几个好处

  • 无需自定义控制逻辑。对话可以支持大多数类型的有向图,例如作为状态机。
  • 无需维护播放器存储空间。对话为每个玩家提供 session 存储。
  • 默认情况下对话是模态的。所有发送给玩家的正常消息都会被抑制。对话也可以是非模式的,允许正常的消息流动。
  • 动态提示生成,可以更好地表示对话的状态。
  • 无需跟踪。对话可能会在一段时间后超时。
  • 不提供家政服务。如果玩家注销,对话就会自行释放。

Note the use of sendRawMessage() during the conversation, as it does not check conversation state as sendMessage() does.

以下代码是使用Conversations的实现。再次强调,此代码用于教育和演示目的。使用风险由您自行承担。

public class ConvoTagController implements Listener {
private static final String VALID_COLOR_PAT = "^[a-f0-9]$";
private final ConversationFactory factory;


public ConvoTagController( JavaPlugin plugin ) {
this.factory = new ConversationFactory( plugin );
Bukkit.getPluginManager().registerEvents( this, plugin );
}


@EventHandler( ignoreCancelled = true )
public void onPlayerInteract( PlayerInteractEvent event ) {
if ( event.getAction() != Action.RIGHT_CLICK_BLOCK )
return;

Block block = event.getClickedBlock();

Player player = event.getPlayer();
if ( block.getType() == Material.WALL_SIGN ) {
// Other tests to make sure its the right sign
if ( !player.isConversing() )
startConversation( player );
}
}


/**
* Trigger the start of a player's conversation. This would be called by your sign
* interaction handler or started by a command.
*
* @param player player for which conversation is to be started
*/
private void startConversation( Player player ) {
factory.withFirstPrompt( new PrefixPrompt() ).withPrefix( new TagPrefix() )
.withLocalEcho( false ).withEscapeSequence( "clear" ).buildConversation( player )
.begin();
}

public class TagPrefix implements ConversationPrefix {

@Override
public String getPrefix( ConversationContext context ) {
return ChatColor.BLUE + "[TAGS] " + ChatColor.WHITE;
}

}

public class PrefixPrompt extends ValidatingPrompt {

@Override
public String getPromptText( ConversationContext context ) {
return "Enter a prefix (type 'clear' to quit)";
}


@Override
protected boolean isInputValid( ConversationContext context, String input ) {
// TODO Test to make sure prefix is valid
return true;
}


@Override
protected Prompt acceptValidatedInput( ConversationContext context, String input ) {
context.setSessionData( "prefix", input );
return new BracketColor();
}
}

public class BracketColor extends ValidatingPrompt {

@Override
public String getPromptText( ConversationContext context ) {
return "Enter a bracket color (type 'clear' to quit)";
}


@Override
protected boolean isInputValid( ConversationContext context, String input ) {
return input.matches( VALID_COLOR_PAT );
}


@Override
protected Prompt acceptValidatedInput( ConversationContext context, String input ) {
context.setSessionData( "bracket", input );
return new NameColor();
}

}

public class NameColor extends ValidatingPrompt {

@Override
public String getPromptText( ConversationContext context ) {
return "Enter a name color (type 'clear' to quit)";
}


@Override
protected boolean isInputValid( ConversationContext context, String input ) {
return input.matches( VALID_COLOR_PAT );
}


@Override
protected Prompt acceptValidatedInput( ConversationContext context, String input ) {
context.setSessionData( "name", input );
return new Done();
}
}

public class Done implements Prompt {

@Override
public String getPromptText( ConversationContext context ) {
Conversable c = context.getForWhom();
String prefix = (String) context.getSessionData( "prefix" );
String bracket = (String) context.getSessionData( "bracket" );
String name = (String) context.getSessionData( "name" );

c.sendRawMessage( "Prefix selected: " + prefix );
c.sendRawMessage( "Bracket color selected: " + bracket );
c.sendRawMessage( "Name color selected: " + name );

if ( c instanceof Player ) {
Player p = (Player) c;
// Do whatever you need to do to player specifically.
}
return "Thank you, your settings will now take effect";
}


@Override
public boolean blocksForInput( ConversationContext context ) {
return false;
}


@Override
public Prompt acceptInput( ConversationContext context, String input ) {
return END_OF_CONVERSATION;
}
}
}

关于java - Spigot API - 从玩家获取多个字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42430102/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com