ColorCode supported Info Chat
Externer Inhalt
www.youtube.com
Inhalte von externen Seiten werden ohne Ihre Zustimmung nicht automatisch geladen und angezeigt.
Durch die Aktivierung der externen Inhalte erklären Sie sich damit einverstanden, dass personenbezogene Daten an Drittplattformen übermittelt werden. Mehr Informationen dazu haben wir in unserer Datenschutzerklärung zur Verfügung gestellt.
https://www.youtube.com/watch?v=65JCdFzNLAM
Das ist ein Info Chat, der PlayerTextdraws erstellt und diese in einer einstellbaren Zeit erscheinen lässt (mit Animation) und diesen PlayerTextdraw eine einstellbare Zeit anzeigt.
Java: ChatMessage.java
/**
*
*/
package me.alf21.util.chat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.gtaun.shoebill.constant.TextDrawAlign;
import net.gtaun.shoebill.constant.TextDrawFont;
import net.gtaun.shoebill.data.Color;
import net.gtaun.shoebill.object.Destroyable;
import net.gtaun.shoebill.object.Player;
import net.gtaun.shoebill.object.PlayerTextdraw;
import net.gtaun.shoebill.object.Timer;
/**
* @author Alf21
*
*/
public class ChatMessage implements Destroyable{
private PlayerTextdraw textdraw;
private int slot;
private Timer timer;
private boolean sliding;
private String text;
private int count;
private Player player;
private Long time;
private int currentEndIndex;
public ChatMessage(Player player, String text, int slot) {
this.player = player;
this.text = removeNonColorCodes(text).trim();
this.slot = slot;
count = 1;
createTextdraw(0,0);
time = System.currentTimeMillis();
}
public void slideIn() {
sliding = true;
reset();
final int length = getTextLength();
final int interval = (int) Chat.slideTime/length;
currentEndIndex = 0;
timer = Timer.create(interval, length, (factualInterval) -> {
currentEndIndex++;
currentEndIndex = cutTextIn(currentEndIndex);
textdraw.hide();
textdraw.setText(text.substring(0, currentEndIndex));
textdraw.show();
if(count == length) {
sliding = false;
timer.stop();
}
count++;
});
timer.start();
}
public void slideOut() {
sliding = true;
reset();
final int length = getTextLength();
final int interval = (int) Chat.slideTime/length;
currentEndIndex = text.length();
timer = Timer.create(interval, length-1, (factualInterval) -> {
currentEndIndex--;
currentEndIndex = cutTextOut(currentEndIndex);
textdraw.hide();
textdraw.setText(text.substring(0, currentEndIndex));
textdraw.show();
if(count == length-1) {
sliding = false;
timer.stop();
}
count++;
});
timer.start();
}
public void moveUp() {
reset();
final int maxCount = 15;
final int interval = (int) Chat.slideTime/maxCount;
timer = Timer.create(interval, maxCount, (factualInterval) -> {
textdraw.hide();
textdraw.destroy();
createTextdraw(0, (float) -count*(15f/(float) maxCount));
textdraw.show();
if(count == maxCount) {
slot++;
timer.stop();
}
count++;
});
timer.start();
}
public void hide() {
textdraw.hide();
}
public void show() {
textdraw.show();
}
private void reset() {
if(timer != null)
timer.destroy();
count = 1;
}
private void createTextdraw(float x, float y) {
textdraw = PlayerTextdraw.create(player, 630+x, 385-15*slot+y);
textdraw.setText(text);
textdraw.setAlignment(TextDrawAlign.RIGHT);
textdraw.setBackgroundColor(Color.BLACK);
textdraw.setFont(TextDrawFont.get(1));
textdraw.setLetterSize(0.5f, 1);
textdraw.setColor(Color.WHITE);
textdraw.setOutlineSize(1);
textdraw.setProportional(true);
textdraw.setSelectable(false);
}
/**
* @return the sliding
*/
public boolean isSliding() {
return sliding;
}
/**
* @param sliding the sliding to set
*/
public void setSliding(boolean sliding) {
this.sliding = sliding;
}
/**
* @return the time when textdraw was created
*/
public Long getTime() {
return time;
}
/**
* @return the textdraw
*/
public PlayerTextdraw getTextdraw() {
return textdraw;
}
/**
* @return the player
*/
public Player getPlayer() {
return player;
}
/* (non-Javadoc)
* @see net.gtaun.shoebill.object.Destroyable#destroy()
*/
@Override
public void destroy() {
if(timer != null) {
if(timer.isRunning())
timer.stop();
timer.destroy();
timer = null;
}
if(textdraw != null) {
textdraw.hide();
textdraw.destroy();
textdraw = null;
}
}
/* (non-Javadoc)
* @see net.gtaun.shoebill.object.Destroyable#isDestroyed()
*/
@Override
public boolean isDestroyed() {
if(timer != null || textdraw != null)
return false;
return true;
}
private String removeNonColorCodes(String text) {
final String prefixOfColorCodes = "COLOR"; //The prefix of any color code like "COLOR_RED" <- HERE>> if String == "": "_RED"
final String connectionOfColorCodes = "\u005F"; //The connection label or Unicode, here: "\u005F" == "_" <- HERE>> if String == "": "COLORRED"
String replaceStr = prefixOfColorCodes + connectionOfColorCodes;
text = text.replaceAll("\u007E" + "w" + "\u007E", replaceStr + "WHITE");
text = text.replaceAll("\u007E" + "r" + "\u007E", replaceStr + "RED");
text = text.replaceAll("\u007E" + "g" + "\u007E", replaceStr + "GREEN");
text = text.replaceAll("\u007E" + "b" + "\u007E", replaceStr + "DARK" + connectionOfColorCodes + "BLUE");
text = text.replaceAll("\u007E" + "y" + "\u007E", replaceStr + "YELLOW");
text = text.replaceAll("\u007E" + "p" + "\u007E", replaceStr + "PURPLE");
text = text.replaceAll("\u007E" + "l" + "\u007E", replaceStr + "BLACK");
text = text.replaceAll("\u007E" + "h" + "\u007E", replaceStr + "LIGHTER");
text = text.replaceAll("\u007E+([\\w[\u003C\u003E&&[\\S]]]?)\u007E", ""); //replace unknown colors and Commands
text = text.replaceAll("\u007E", ""); //replace other "~"
text = text.replaceAll(replaceStr + "WHITE", "\u007E" + "w" + "\u007E");
text = text.replaceAll(replaceStr + "RED", "\u007E" + "r" + "\u007E");
text = text.replaceAll(replaceStr + "GREEN", "\u007E" + "g" + "\u007E");
text = text.replaceAll(replaceStr + "DARK" + connectionOfColorCodes + "BLUE", "\u007E" + "b" + "\u007E");
text = text.replaceAll(replaceStr + "YELLOW", "\u007E" + "y" + "\u007E");
text = text.replaceAll(replaceStr + "PURPLE", "\u007E" + "p" + "\u007E");
text = text.replaceAll(replaceStr + "BLACK", "\u007E" + "l" + "\u007E");
text = text.replaceAll(replaceStr + "LIGHTER", "\u007E" + "h" + "\u007E");
return text;
}
private int cutTextIn(int endIndex) {
int currentEndIndex = endIndex;
String string = text.substring(0, currentEndIndex);
while(string.trim().length() < string.length()){
currentEndIndex++;
string = text.substring(0, currentEndIndex);
}
//check whether string contains color codes
Matcher matcher = Pattern.compile("\u007E+([\\w[\u003C\u003E&&[\\S]]]{1})\u007E").matcher(text); //~r~|
if(matcher.find()) {
//match ~
int matcherState = 0;
matcher = Pattern.compile("\u007E+([\\w[\u003C\u003E&&[\\S]]]{1})\u007E\\z").matcher(string); //~r~|...
Matcher matcher2 = Pattern.compile("\u007E+([\\w[\u003C\u003E&&[\\S]]]{1})\u007E+([\\w[\u003C\u003E&&[\\S]]]{1})\u007E\\z").matcher(string); //~s~r~|...
if(matcher.find() && !matcher2.find()) {
matcher = Pattern.compile("\u007E+([\\w[\u003C\u003E&&[\\S]]]{1})\u007E\\z").matcher(string); //~r~|...
matcherState = 3;
}
else {
matcher = Pattern.compile("\u007E+([\\w[\u003C\u003E&&[\\S]]]{1})\\z").matcher(string); //~r|...
if(matcher.find()) {
matcher = Pattern.compile("\u007E+([\\w[\u003C\u003E&&[\\S]]]{1})\\z").matcher(string); //~r|...
matcherState = 4;
}
else {
matcher = Pattern.compile("\u007E\\z").matcher(string); //~|...
matcherState = 5;
}
}
while(matcher.find()) {
//check whether color code is after this color code
if(currentEndIndex+matcherState <= text.length()) {
currentEndIndex += matcherState;
string = text.substring(0, currentEndIndex);
while(string.trim().length() < string.length()){
currentEndIndex++;
string = text.substring(0, currentEndIndex);
}
matcher = Pattern.compile("\u007E+([\\w[\u003C\u003E&&[\\S]]]{1})\u007E\\z").matcher(string); //~r~| <- update the matcher
if(!matcher.find()) {
currentEndIndex -= 2;
string = text.substring(0, currentEndIndex);
}
else
matcher = Pattern.compile("\u007E+([\\w[\u003C\u003E&&[\\S]]]{1})\u007E\\z").matcher(string); //~r~| <- update the matcher
matcherState = 3;
}
}
string = text.substring(0, currentEndIndex);
while(string.trim().length() < string.length()){
currentEndIndex++;
string = text.substring(0, currentEndIndex);
}
matcher2 = Pattern.compile("\u007E\\z").matcher(string); //~|...
if(matcher2.find()) {
if(currentEndIndex+3 <= text.length())
currentEndIndex += 3;
}
}
return currentEndIndex;
}
private int cutTextOut(int endIndex) {
int currentEndIndex = endIndex;
String string = text.substring(0, currentEndIndex);
while(string.trim().length() < string.length()){
currentEndIndex--;
string = text.substring(0, currentEndIndex);
}
//check whether string contains color codes
Matcher matcher = Pattern.compile("\u007E+([\\w[\u003C\u003E&&[\\S]]]{1})\u007E").matcher(text); //~r~|
if(matcher.find()) {
//match ~
int matcherState = 0;
matcher = Pattern.compile("\u007E+([\\w[\u003C\u003E&&[\\S]]]{1})\u007E\\z").matcher(string); //~r~|...
if(matcher.find()) {
matcher = Pattern.compile("\u007E+([\\w[\u003C\u003E&&[\\S]]]{1})\u007E\\z").matcher(string); //~r~|...
matcherState = 3;
}
else {
matcher = Pattern.compile("\u007E+([\\w[\u003C\u003E&&[\\S]]]{1})\\z").matcher(string); //~r|...
String string2 = text.substring(0, currentEndIndex+1);
Matcher matcher2 = Pattern.compile("\u007E+([\\w[\u003C\u003E&&[\\S]]]{1})\u007E\\z").matcher(string2); //~r~|...
if(matcher.find() && matcher2.find()) {
matcher = Pattern.compile("\u007E+([\\w[\u003C\u003E&&[\\S]]]{1})\\z").matcher(string); //~r|...
matcherState = 2;
}
else {
matcher = Pattern.compile("\u007E\\z").matcher(string); //~|...
matcherState = 1;
}
}
while(matcher.find()) {
//check whether color code is before this color code
if(currentEndIndex-matcherState > 0) {
currentEndIndex -= matcherState;
string = text.substring(0, currentEndIndex);
while(string.trim().length() < string.length()){
currentEndIndex--;
string = text.substring(0, currentEndIndex);
}
matcher = Pattern.compile("\u007E+([\\w[\u003C\u003E&&[\\S]]]{1})\u007E\\z").matcher(string); //~r~| <- update the matcher
matcherState = 3;
}
}
string = text.substring(0, currentEndIndex);
while(string.trim().length() < string.length()){
currentEndIndex--;
string = text.substring(0, currentEndIndex);
}
}
return currentEndIndex;
}
private int getTextLength() {
int length = text.replace(" ", "").length();
Matcher matcher = Pattern.compile("\u007E+([\\w[\u003C\u003E&&[\\S]]]{1})\u007E").matcher(text); //~r~
while(matcher.find()) {
length -= 3;
}
return length;
}
}
Alles anzeigen
Java: Chat.java
/**
*
*/
package me.alf21.util.chat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import net.gtaun.shoebill.object.Destroyable;
import net.gtaun.shoebill.object.Player;
import net.gtaun.shoebill.object.Timer;
/**
* @author Alf21
*/
public class Chat implements Destroyable {
private Timer timer;
public static final int updateDelay = 50;
public static final int displayTime = 5000;
public static final int slideTime = 500;
private ArrayList<ChatMessage> chatMessages;
private ChatMessage currentChatMessage;
private Map<Player, String> queue;
public Chat() {
reset();
initializeTimer();
}
//TODO Chat right bottom Corner, with new Infos sliding down if new message received
// 5 Slots, 6 available Textdraws
public void sendMessage(Player player, String text) {
if(chatMessages != null && chatMessages.size() > 5) {
//slide getSlot > 5 out
}
queue.put(player, text);
if(!timer.isRunning())
timer.start();
}
private void reset() {
if(chatMessages != null && !chatMessages.isEmpty()) {
chatMessages.stream().forEach((chatMessage) -> {
chatMessage.hide();
chatMessage.destroy();
});
}
chatMessages = new ArrayList<ChatMessage>();
queue = new HashMap<Player, String>();
currentChatMessage = null;
}
private void initializeTimer() {
timer = Timer.create(updateDelay, (factualInterval) -> {
Long systemTime = System.currentTimeMillis();
ArrayList<ChatMessage> removeMessages = new ArrayList<ChatMessage>(); //TODO Solution with Iterator
if(chatMessages != null && !chatMessages.isEmpty()) {
chatMessages.stream().forEach((chatMessage) -> {
if(systemTime-chatMessage.getTime() >= slideTime) {
if(currentChatMessage != null) {
currentChatMessage = null;
}
}
if(systemTime-chatMessage.getTime() >= displayTime+2*slideTime) {
removeMessages.add(chatMessage);
}
else if(systemTime-chatMessage.getTime() >= displayTime+slideTime) {
if(!chatMessage.isSliding()) {
chatMessage.slideOut();
}
}
});
removeMessages.stream().forEach((removeMessage) -> {
removeChatMessage(removeMessage);
});
removeMessages.clear();
}
if(currentChatMessage == null && !queue.isEmpty()) {
Map.Entry<Player,String> entry = queue.entrySet().iterator().next();
Player player = entry.getKey();
currentChatMessage = new ChatMessage(player, entry.getValue(), 0);
queue.remove(player);
chatMessages.add(currentChatMessage);
}
if(currentChatMessage != null) {
if(chatMessages.size() > 1) {
chatMessages.stream().forEach((chatMessage) -> {
if(chatMessage != currentChatMessage)
chatMessage.moveUp();
});
}
if(!currentChatMessage.isSliding()) {
currentChatMessage.slideIn();
}
}
if(chatMessages != null && chatMessages.isEmpty()) {
timer.stop();
reset();
}
});
}
private void removeChatMessage(ChatMessage chatMessage) {
if(chatMessages.contains(chatMessage)) {
chatMessages.remove(chatMessage);
}
chatMessage.destroy();
}
/* (non-Javadoc)
* @see net.gtaun.shoebill.object.Destroyable#destroy()
*/
@Override
public void destroy() {
if(timer != null) {
if(timer.isRunning())
timer.stop();
timer.destroy();
timer = null;
}
if(currentChatMessage != null) {
currentChatMessage.destroy();
currentChatMessage = null;
}
if(chatMessages != null) {
chatMessages.stream().forEach((chatMessage) -> chatMessage.destroy());
chatMessages = null;
}
if(queue != null) {
queue = null;
}
}
/* (non-Javadoc)
* @see net.gtaun.shoebill.object.Destroyable#isDestroyed()
*/
@Override
public boolean isDestroyed() {
if(timer != null || currentChatMessage != null || chatMessages != null || queue != null)
return false;
return true;
}
//TODO: add background box and increase if new message and resize on message destroy
}
Alles anzeigen
Nutzung:
In einem Plugin bei onEnable() oder im Gamemode bei onInit() den Chat initialisieren, indem ihr die Referenz speichert (Chat chat = new Chat()) und bei onDisable() den Chat mit chat.destroy(); zerstören und dann z.B. unter Commands
Java
@Command
@CommandHelp("/chatme")
public boolean chatme(Player player, String msg) {
EventSystem.getInstance().getChat().sendMessage(player, msg);
return true;
}
Ich würde mich über ein Feedback oder Ideen freuen!