Add packet update delay setting

This commit is contained in:
fullwall 2014-02-18 20:29:21 +08:00
parent e248d3f7f9
commit f897ab728d
4 changed files with 261 additions and 261 deletions

View File

@ -58,27 +58,27 @@ public class Settings {
CHAT_FORMAT_TO_TARGET("npc.chat.format.to-target", "[<npc>] -> You: <text>"), CHAT_FORMAT_TO_TARGET("npc.chat.format.to-target", "[<npc>] -> You: <text>"),
CHAT_FORMAT_WITH_TARGETS_TO_BYSTANDERS("npc.chat.format.with-targets-to-bystanders", CHAT_FORMAT_WITH_TARGETS_TO_BYSTANDERS("npc.chat.format.with-targets-to-bystanders",
"[<npc>] -> [<targets>]: <text>"), "[<npc>] -> [<targets>]: <text>"),
CHAT_MAX_NUMBER_OF_TARGETS("npc.chat.options.max-number-of-targets-to-show", 2), CHAT_MAX_NUMBER_OF_TARGETS("npc.chat.options.max-number-of-targets-to-show", 2),
CHAT_MULTIPLE_TARGETS_FORMAT("npc.chat.options.multiple-targets-format", CHAT_MULTIPLE_TARGETS_FORMAT("npc.chat.options.multiple-targets-format",
"<target>|, <target>| & <target>| & others"), "<target>|, <target>| & <target>| & others"),
CHAT_RANGE("npc.chat.options.range", 5), CHAT_RANGE("npc.chat.options.range", 5),
CHECK_MINECRAFT_VERSION("advanced.check-minecraft-version", true), CHECK_MINECRAFT_VERSION("advanced.check-minecraft-version", true),
DATABASE_DRIVER("storage.database.driver", ""), DATABASE_DRIVER("storage.database.driver", ""),
DATABASE_PASSWORD("storage.database.password", ""), DATABASE_PASSWORD("storage.database.password", ""),
DATABASE_URL("storage.database.url", ""), DATABASE_URL("storage.database.url", ""),
DATABASE_USERNAME("storage.database.username", ""), DATABASE_USERNAME("storage.database.username", ""),
DEBUG_MODE("general.debug-mode", false), DEBUG_MODE("general.debug-mode", false),
DEBUG_PATHFINDING("general.debug-pathfinding", false), DEBUG_PATHFINDING("general.debug-pathfinding", false),
DEFAULT_LOOK_CLOSE("npc.default.look-close.enabled", false), DEFAULT_LOOK_CLOSE("npc.default.look-close.enabled", false),
DEFAULT_LOOK_CLOSE_RANGE("npc.default.look-close.range", 5), DEFAULT_LOOK_CLOSE_RANGE("npc.default.look-close.range", 5),
DEFAULT_NPC_LIMIT("npc.limits.default-limit", 10), DEFAULT_NPC_LIMIT("npc.limits.default-limit", 10),
DEFAULT_PATHFINDING_RANGE("npc.default.pathfinding.range", 25F), DEFAULT_PATHFINDING_RANGE("npc.default.pathfinding.range", 25F),
DEFAULT_RANDOM_TALKER("npc.default.random-talker", true), DEFAULT_RANDOM_TALKER("npc.default.random-talker", true),
DEFAULT_REALISTIC_LOOKING("npc.default.realistic-looking", false), DEFAULT_REALISTIC_LOOKING("npc.default.realistic-looking", false),
DEFAULT_STATIONARY_TICKS("npc.default.stationary-ticks", -1), DEFAULT_STATIONARY_TICKS("npc.default.stationary-ticks", -1),
DEFAULT_TALK_CLOSE("npc.default.talk-close.enabled", false), DEFAULT_TALK_CLOSE("npc.default.talk-close.enabled", false),
DEFAULT_TALK_CLOSE_RANGE("npc.default.talk-close.range", 5), DEFAULT_TALK_CLOSE_RANGE("npc.default.talk-close.range", 5),
DEFAULT_TEXT("npc.default.text.0", "Hi, I'm <npc>!") { DEFAULT_TEXT("npc.default.text.0", "Hi, I'm <npc>!") {
@Override @Override
public void loadFromKey(DataKey root) { public void loadFromKey(DataKey root) {
List<String> list = new ArrayList<String>(); List<String> list = new ArrayList<String>();
@ -96,6 +96,7 @@ public class Settings {
MESSAGE_COLOUR("general.color-scheme.message", "<a>"), MESSAGE_COLOUR("general.color-scheme.message", "<a>"),
NPC_ATTACK_DISTANCE("npc.pathfinding.attack-range", 1.75 * 1.75), NPC_ATTACK_DISTANCE("npc.pathfinding.attack-range", 1.75 * 1.75),
NPC_COST("economy.npc.cost", 100D), NPC_COST("economy.npc.cost", 100D),
PACKET_UPDATE_DELAY("npc.packets.update-delay", 30),
QUICK_SELECT("npc.selection.quick-select", false), QUICK_SELECT("npc.selection.quick-select", false),
REMOVE_PLAYERS_FROM_PLAYER_LIST("npc.player.remove-from-list", true), REMOVE_PLAYERS_FROM_PLAYER_LIST("npc.player.remove-from-list", true),
SAVE_TASK_DELAY("storage.save-task.delay", 20 * 60 * 60), SAVE_TASK_DELAY("storage.save-task.delay", 20 * 60 * 60),

View File

@ -217,7 +217,8 @@ public class CitizensNPC extends AbstractNPC {
} }
navigator.run(); navigator.run();
if (!getNavigator().isNavigating() && getEntity().getWorld().getTime() % 30 == 0) { if (!getNavigator().isNavigating()
&& getEntity().getWorld().getTime() % Setting.PACKET_UPDATE_DELAY.asInt() == 0) {
Player player = getEntity() instanceof Player ? (Player) getEntity() : null; Player player = getEntity() instanceof Player ? (Player) getEntity() : null;
NMS.sendPacketNearby(player, getStoredLocation(), NMS.sendPacketNearby(player, getStoredLocation(),
new PacketPlayOutEntityTeleport(NMS.getHandle(getEntity()))); new PacketPlayOutEntityTeleport(NMS.getHandle(getEntity())));

View File

@ -52,7 +52,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
private PlayerNavigation navigation; private PlayerNavigation navigation;
private final CitizensNPC npc; private final CitizensNPC npc;
private final Location packetLocationCache = new Location(null, 0, 0, 0); private final Location packetLocationCache = new Location(null, 0, 0, 0);
private int packetUpdateCount;
private int useListName = -1; private int useListName = -1;
public EntityHumanNPC(MinecraftServer minecraftServer, WorldServer world, GameProfile gameProfile, public EntityHumanNPC(MinecraftServer minecraftServer, WorldServer world, GameProfile gameProfile,
@ -258,7 +257,7 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
} }
private void updatePackets(boolean navigating) { private void updatePackets(boolean navigating) {
if (++packetUpdateCount >= 30) { if (world.getWorld().getTime() % Setting.PACKET_UPDATE_DELAY.asInt() == 0) {
Location current = getBukkitEntity().getLocation(packetLocationCache); Location current = getBukkitEntity().getLocation(packetLocationCache);
Packet[] packets = new Packet[navigating ? 6 : 7]; Packet[] packets = new Packet[navigating ? 6 : 7];
if (!navigating) { if (!navigating) {
@ -278,7 +277,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
removeFromPlayerList ? 9999 : ping); removeFromPlayerList ? 9999 : ping);
} }
NMS.sendPacketsNearby(getBukkitEntity(), current, packets); NMS.sendPacketsNearby(getBukkitEntity(), current, packets);
packetUpdateCount = 0;
} }
} }

View File

@ -1,237 +1,237 @@
package net.citizensnpcs.trait.text; package net.citizensnpcs.trait.text;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.ai.speech.SpeechContext; import net.citizensnpcs.api.ai.speech.SpeechContext;
import net.citizensnpcs.api.event.NPCRightClickEvent; import net.citizensnpcs.api.event.NPCRightClickEvent;
import net.citizensnpcs.api.exception.NPCLoadException; import net.citizensnpcs.api.exception.NPCLoadException;
import net.citizensnpcs.api.trait.Trait; import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.util.DataKey; import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.api.util.Messaging; import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.api.util.Paginator; import net.citizensnpcs.api.util.Paginator;
import net.citizensnpcs.editor.Editor; import net.citizensnpcs.editor.Editor;
import net.citizensnpcs.trait.Toggleable; import net.citizensnpcs.trait.Toggleable;
import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.Messages;
import net.citizensnpcs.util.Util; import net.citizensnpcs.util.Util;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.conversations.Conversation; import org.bukkit.conversations.Conversation;
import org.bukkit.conversations.ConversationAbandonedEvent; import org.bukkit.conversations.ConversationAbandonedEvent;
import org.bukkit.conversations.ConversationAbandonedListener; import org.bukkit.conversations.ConversationAbandonedListener;
import org.bukkit.conversations.ConversationFactory; import org.bukkit.conversations.ConversationFactory;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
public class Text extends Trait implements Runnable, Toggleable, Listener, ConversationAbandonedListener { public class Text extends Trait implements Runnable, Toggleable, Listener, ConversationAbandonedListener {
private final Map<String, Date> cooldowns = Maps.newHashMap(); private final Map<String, Date> cooldowns = Maps.newHashMap();
private int currentIndex; private int currentIndex;
private String itemInHandPattern = "default"; private String itemInHandPattern = "default";
private final Plugin plugin; private final Plugin plugin;
private boolean randomTalker = Setting.DEFAULT_RANDOM_TALKER.asBoolean(); private boolean randomTalker = Setting.DEFAULT_RANDOM_TALKER.asBoolean();
private double range = Setting.DEFAULT_TALK_CLOSE_RANGE.asDouble(); private double range = Setting.DEFAULT_TALK_CLOSE_RANGE.asDouble();
private boolean realisticLooker = Setting.DEFAULT_REALISTIC_LOOKING.asBoolean(); private boolean realisticLooker = Setting.DEFAULT_REALISTIC_LOOKING.asBoolean();
private boolean talkClose = Setting.DEFAULT_TALK_CLOSE.asBoolean(); private boolean talkClose = Setting.DEFAULT_TALK_CLOSE.asBoolean();
private final List<String> text = new ArrayList<String>(); private final List<String> text = new ArrayList<String>();
public Text() { public Text() {
super("text"); super("text");
this.plugin = CitizensAPI.getPlugin(); this.plugin = CitizensAPI.getPlugin();
} }
void add(String string) { void add(String string) {
text.add(string); text.add(string);
} }
@Override @Override
public void conversationAbandoned(ConversationAbandonedEvent event) { public void conversationAbandoned(ConversationAbandonedEvent event) {
Bukkit.dispatchCommand((Player) event.getContext().getForWhom(), "npc text"); Bukkit.dispatchCommand((Player) event.getContext().getForWhom(), "npc text");
} }
void edit(int index, String newText) { void edit(int index, String newText) {
text.set(index, newText); text.set(index, newText);
} }
public Editor getEditor(final Player player) { public Editor getEditor(final Player player) {
final Conversation conversation = new ConversationFactory(plugin).addConversationAbandonedListener(this) final Conversation conversation = new ConversationFactory(plugin).addConversationAbandonedListener(this)
.withLocalEcho(false).withEscapeSequence("/npc text").withEscapeSequence("exit").withModality(false) .withLocalEcho(false).withEscapeSequence("/npc text").withEscapeSequence("exit").withModality(false)
.withFirstPrompt(new TextStartPrompt(this)).buildConversation(player); .withFirstPrompt(new TextStartPrompt(this)).buildConversation(player);
return new Editor() { return new Editor() {
@Override @Override
public void begin() { public void begin() {
Messaging.sendTr(player, Messages.TEXT_EDITOR_BEGIN); Messaging.sendTr(player, Messages.TEXT_EDITOR_BEGIN);
conversation.begin(); conversation.begin();
} }
@Override @Override
public void end() { public void end() {
Messaging.sendTr(player, Messages.TEXT_EDITOR_END); Messaging.sendTr(player, Messages.TEXT_EDITOR_END);
conversation.abandon(); conversation.abandon();
} }
}; };
} }
boolean hasIndex(int index) { boolean hasIndex(int index) {
return index >= 0 && text.size() > index; return index >= 0 && text.size() > index;
} }
@Override @Override
public void load(DataKey key) throws NPCLoadException { public void load(DataKey key) throws NPCLoadException {
text.clear(); text.clear();
// TODO: legacy, remove later // TODO: legacy, remove later
for (DataKey sub : key.getIntegerSubKeys()) { for (DataKey sub : key.getIntegerSubKeys()) {
text.add(sub.getString("")); text.add(sub.getString(""));
} }
for (DataKey sub : key.getRelative("text").getIntegerSubKeys()) { for (DataKey sub : key.getRelative("text").getIntegerSubKeys()) {
text.add(sub.getString("")); text.add(sub.getString(""));
} }
if (text.isEmpty()) { if (text.isEmpty()) {
populateDefaultText(); populateDefaultText();
} }
talkClose = key.getBoolean("talk-close", talkClose); talkClose = key.getBoolean("talk-close", talkClose);
realisticLooker = key.getBoolean("realistic-looking", realisticLooker); realisticLooker = key.getBoolean("realistic-looking", realisticLooker);
randomTalker = key.getBoolean("random-talker", randomTalker); randomTalker = key.getBoolean("random-talker", randomTalker);
range = key.getDouble("range", range); range = key.getDouble("range", range);
itemInHandPattern = key.getString("talkitem", itemInHandPattern); itemInHandPattern = key.getString("talkitem", itemInHandPattern);
} }
@EventHandler @EventHandler
public void onRightClick(NPCRightClickEvent event) { public void onRightClick(NPCRightClickEvent event) {
if (!event.getNPC().equals(npc)) if (!event.getNPC().equals(npc))
return; return;
String localPattern = itemInHandPattern.equals("default") ? Setting.TALK_ITEM.asString() : itemInHandPattern; String localPattern = itemInHandPattern.equals("default") ? Setting.TALK_ITEM.asString() : itemInHandPattern;
if (Util.matchesItemInHand(event.getClicker(), localPattern) && !shouldTalkClose()) { if (Util.matchesItemInHand(event.getClicker(), localPattern) && !shouldTalkClose()) {
sendText(event.getClicker()); sendText(event.getClicker());
} }
} }
private void populateDefaultText() { private void populateDefaultText() {
text.addAll(Setting.DEFAULT_TEXT.asList()); text.addAll(Setting.DEFAULT_TEXT.asList());
} }
void remove(int index) { void remove(int index) {
text.remove(index); text.remove(index);
} }
@Override @Override
public void run() { public void run() {
if (!talkClose || !npc.isSpawned()) if (!talkClose || !npc.isSpawned())
return; return;
List<Entity> nearby = npc.getEntity().getNearbyEntities(range, range, range); List<Entity> nearby = npc.getEntity().getNearbyEntities(range, range, range);
for (Entity search : nearby) { for (Entity search : nearby) {
if (!(search instanceof Player)) if (!(search instanceof Player))
continue; continue;
Player player = (Player) search; Player player = (Player) search;
// If the cooldown is not expired, do not send text // If the cooldown is not expired, do not send text
Date cooldown = cooldowns.get(player.getName()); Date cooldown = cooldowns.get(player.getName());
if (cooldown != null) { if (cooldown != null) {
if (!new Date().after(cooldown)) { if (!new Date().after(cooldown)) {
return; return;
} }
cooldowns.remove(player.getName()); cooldowns.remove(player.getName());
} }
if (!sendText(player)) if (!sendText(player))
return; return;
// Add a cooldown if the text was successfully sent // Add a cooldown if the text was successfully sent
Date wait = new Date(); Date wait = new Date();
int secondsDelta = RANDOM.nextInt(Setting.TALK_CLOSE_MAXIMUM_COOLDOWN.asInt()) int secondsDelta = RANDOM.nextInt(Setting.TALK_CLOSE_MAXIMUM_COOLDOWN.asInt())
+ Setting.TALK_CLOSE_MINIMUM_COOLDOWN.asInt(); + Setting.TALK_CLOSE_MINIMUM_COOLDOWN.asInt();
if (secondsDelta <= 0) if (secondsDelta <= 0)
return; return;
long millisecondsDelta = TimeUnit.MILLISECONDS.convert(secondsDelta, TimeUnit.SECONDS); long millisecondsDelta = TimeUnit.MILLISECONDS.convert(secondsDelta, TimeUnit.SECONDS);
wait.setTime(wait.getTime() + millisecondsDelta); wait.setTime(wait.getTime() + millisecondsDelta);
cooldowns.put(player.getName(), wait); cooldowns.put(player.getName(), wait);
} }
} }
@Override @Override
public void save(DataKey key) { public void save(DataKey key) {
key.setBoolean("talk-close", talkClose); key.setBoolean("talk-close", talkClose);
key.setBoolean("random-talker", randomTalker); key.setBoolean("random-talker", randomTalker);
key.setBoolean("realistic-looking", realisticLooker); key.setBoolean("realistic-looking", realisticLooker);
key.setDouble("range", range); key.setDouble("range", range);
key.setString("talkitem", itemInHandPattern); key.setString("talkitem", itemInHandPattern);
// TODO: legacy, remove later // TODO: legacy, remove later
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
key.removeKey(String.valueOf(i)); key.removeKey(String.valueOf(i));
key.removeKey("text"); key.removeKey("text");
for (int i = 0; i < text.size(); i++) for (int i = 0; i < text.size(); i++)
key.setString("text." + String.valueOf(i), text.get(i)); key.setString("text." + String.valueOf(i), text.get(i));
} }
boolean sendPage(Player player, int page) { boolean sendPage(Player player, int page) {
Paginator paginator = new Paginator().header(npc.getName() + "'s Text Entries"); Paginator paginator = new Paginator().header(npc.getName() + "'s Text Entries");
for (int i = 0; i < text.size(); i++) for (int i = 0; i < text.size(); i++)
paginator.addLine("<a>" + i + " <7>- <e>" + text.get(i)); paginator.addLine("<a>" + i + " <7>- <e>" + text.get(i));
return paginator.sendPage(player, page); return paginator.sendPage(player, page);
} }
private boolean sendText(Player player) { private boolean sendText(Player player) {
if (!player.hasPermission("citizens.admin") && !player.hasPermission("citizens.npc.talk")) if (!player.hasPermission("citizens.admin") && !player.hasPermission("citizens.npc.talk"))
return false; return false;
if (text.size() == 0) if (text.size() == 0)
return false; return false;
int index = 0; int index = 0;
if (randomTalker) if (randomTalker)
index = RANDOM.nextInt(text.size()); index = RANDOM.nextInt(text.size());
else { else {
if (currentIndex > text.size() - 1) if (currentIndex > text.size() - 1)
currentIndex = 0; currentIndex = 0;
index = currentIndex++; index = currentIndex++;
} }
npc.getDefaultSpeechController().speak(new SpeechContext(text.get(index), player)); npc.getDefaultSpeechController().speak(new SpeechContext(text.get(index), player));
return true; return true;
} }
void setItemInHandPattern(String pattern) { void setItemInHandPattern(String pattern) {
itemInHandPattern = pattern; itemInHandPattern = pattern;
} }
void setRange(double range) { void setRange(double range) {
this.range = range; this.range = range;
} }
boolean shouldTalkClose() { boolean shouldTalkClose() {
return talkClose; return talkClose;
} }
@Override @Override
public boolean toggle() { public boolean toggle() {
return (talkClose = !talkClose); return (talkClose = !talkClose);
} }
boolean toggleRandomTalker() { boolean toggleRandomTalker() {
return (randomTalker = !randomTalker); return (randomTalker = !randomTalker);
} }
boolean toggleRealisticLooking() { boolean toggleRealisticLooking() {
return (realisticLooker = !realisticLooker); return (realisticLooker = !realisticLooker);
} }
@Override @Override
public String toString() { public String toString() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append("Text{talk-close=" + talkClose + ",text="); builder.append("Text{talk-close=" + talkClose + ",text=");
for (String line : text) for (String line : text)
builder.append(line + ","); builder.append(line + ",");
builder.append("}"); builder.append("}");
return builder.toString(); return builder.toString();
} }
private static Random RANDOM = Util.getFastRandom(); private static Random RANDOM = Util.getFastRandom();
} }