Merge remote-tracking branch 'refs/remotes/origin/develop' into update/moba-cosmetics
This commit is contained in:
commit
9b04361c6b
@ -20,7 +20,7 @@ public class NautHashMap<KeyType, ValueType>
|
||||
{
|
||||
Validate.isTrue(keys.length == values.length, "Keys array and values array must be the same size when making a Map");
|
||||
|
||||
UtilCollections.loop(0, keys.length, i -> _wrappedHashMap.put(keys[i.intValue()], values[i.intValue()]));
|
||||
UtilCollections.loop(0, keys.length, i -> _wrappedHashMap.put(keys[i], values[i]));
|
||||
}
|
||||
|
||||
public boolean containsKey(KeyType key)
|
||||
|
@ -739,7 +739,7 @@ public class CoreClientManager extends MiniPlugin
|
||||
{
|
||||
_repository.fetchGroups(accountId, (primaryGroup, additionalGroups) ->
|
||||
{
|
||||
if (primaryGroup == null)
|
||||
if (primaryGroup != null)
|
||||
{
|
||||
UtilServer.runSync(() -> resultCallback.accept(primaryGroup, additionalGroups));
|
||||
return;
|
||||
|
@ -76,15 +76,15 @@ public class ResetPlayerCommand extends CommandBase<CoreClientManager>
|
||||
{
|
||||
Plugin.runSync(() ->
|
||||
{
|
||||
if (id.intValue() == -1)
|
||||
if (id == -1)
|
||||
{
|
||||
UtilPlayer.message(caller, F.main(Plugin.getName(), F.elem(target) + " was not found!"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Plugin.clearGroups(id.intValue(), success ->
|
||||
Plugin.clearGroups(id, success ->
|
||||
{
|
||||
if (success.booleanValue())
|
||||
if (success)
|
||||
{
|
||||
UtilPlayer.message(caller, F.main(Plugin.getName(), "You have cleared " + F.elem(target + "'s") + " ranks!"));
|
||||
}
|
||||
@ -101,4 +101,4 @@ public class ResetPlayerCommand extends CommandBase<CoreClientManager>
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -360,7 +360,7 @@ public class AccountRepository extends MinecraftRepository
|
||||
}
|
||||
}
|
||||
|
||||
executeUpdate(c, UPDATE_PRIMARY_RANK, () -> {}, new ColumnVarChar("rankIdentifier", "player".length(), "player"), new ColumnInt("accountId", accountId));
|
||||
executeUpdate(c, UPDATE_PRIMARY_RANK, () -> {}, new ColumnVarChar("rankIdentifier", 255, "PLAYER"), new ColumnInt("accountId", accountId));
|
||||
executeUpdate(c, REMOVE_ADDITIONAL_RANKS, () -> success.set(false), new ColumnInt("accountId", accountId));
|
||||
}
|
||||
catch (SQLException e)
|
||||
|
@ -12,14 +12,14 @@ import mineplex.core.gadget.types.WinEffectGadget;
|
||||
*/
|
||||
public abstract class WinEffectRankBased extends WinEffectGadget
|
||||
{
|
||||
|
||||
private static final String RANK_SCHEMATIC_PREFIX = "WinRank";
|
||||
private final PermissionGroup _rank;
|
||||
|
||||
public WinEffectRankBased(GadgetManager manager, String name, String[] lore, Material material, byte data, int cost, PermissionGroup rank, String... alternativeSalepackageNames)
|
||||
{
|
||||
super(manager, name, lore, cost, material, data, true, alternativeSalepackageNames);
|
||||
_rank = rank;
|
||||
_schematicName = "WinRank" + _rank.getDisplay(false, false, false, false);
|
||||
_schematicName = RANK_SCHEMATIC_PREFIX + rank.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,99 @@
|
||||
package mineplex.core.scoreboard;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutPlayerInfo;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.account.permissions.Permission;
|
||||
import mineplex.core.account.permissions.PermissionGroup;
|
||||
import mineplex.core.command.CommandBase;
|
||||
import mineplex.core.packethandler.IPacketHandler;
|
||||
import mineplex.core.packethandler.PacketHandler;
|
||||
import mineplex.core.packethandler.PacketInfo;
|
||||
|
||||
/**
|
||||
* Sorts the tab list by rank weight (or some other arbitrary metric if you want)
|
||||
* @author Dan
|
||||
*/
|
||||
public class TabListSorter extends MiniPlugin implements IPacketHandler
|
||||
{
|
||||
public enum Perm implements Permission
|
||||
{
|
||||
RANDOM_TAB_LIST
|
||||
}
|
||||
|
||||
private static final Map<PermissionGroup, Integer> WEIGHT;
|
||||
|
||||
static
|
||||
{
|
||||
WEIGHT = new HashMap<>();
|
||||
for (PermissionGroup group : PermissionGroup.values())
|
||||
{
|
||||
if (group.canBePrimary())
|
||||
{
|
||||
WEIGHT.put(group, group.ordinal());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private PacketHandler _packetHandler;
|
||||
private boolean _randomized = false;
|
||||
|
||||
public TabListSorter()
|
||||
{
|
||||
super("TabListSorter");
|
||||
|
||||
generatePermissions();
|
||||
|
||||
// /randomtab - straightforward toggle
|
||||
addCommand(new CommandBase<TabListSorter>(this, Perm.RANDOM_TAB_LIST, "randomtab")
|
||||
{
|
||||
@Override
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
_randomized = !_randomized;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void generatePermissions()
|
||||
{
|
||||
PermissionGroup.DEV.setPermission(Perm.RANDOM_TAB_LIST, true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enable()
|
||||
{
|
||||
_packetHandler = require(PacketHandler.class);
|
||||
_packetHandler.addPacketHandler(this, PacketPlayOutPlayerInfo.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable()
|
||||
{
|
||||
_packetHandler.removePacketHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PacketInfo packetInfo)
|
||||
{
|
||||
if (packetInfo.getPacket() instanceof PacketPlayOutPlayerInfo)
|
||||
{
|
||||
PacketPlayOutPlayerInfo packet = (PacketPlayOutPlayerInfo) packetInfo.getPacket();
|
||||
|
||||
if (_randomized)
|
||||
{
|
||||
Collections.shuffle(packet.b);
|
||||
} else
|
||||
{
|
||||
packet.b.sort(Comparator.comparingInt(info -> WEIGHT.getOrDefault(info, 0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -93,12 +93,12 @@ public class Teleport extends MiniPlugin
|
||||
{
|
||||
runSync(() ->
|
||||
{
|
||||
Player p = Bukkit.getPlayer(command.getUUID());
|
||||
Player p = Bukkit.getPlayer(command.getReceivingPlayerUUID());
|
||||
|
||||
Integer taskId = _failedRankLocates.remove(command.getReceivingPlayerUUID());
|
||||
Integer taskId = _failedRankLocates.remove(command.getUUID());
|
||||
if (taskId != null)
|
||||
{
|
||||
getScheduler().cancelTask(taskId.intValue());
|
||||
getScheduler().cancelTask(taskId);
|
||||
UtilPlayer.message(p, F.main("Locate", "All Online:"));
|
||||
}
|
||||
|
||||
@ -137,7 +137,7 @@ public class Teleport extends MiniPlugin
|
||||
Integer taskId = _failedRedisLocates.remove(callback.getUUID());
|
||||
if (taskId != null)
|
||||
{
|
||||
getScheduler().cancelTask(taskId.intValue());
|
||||
getScheduler().cancelTask(taskId);
|
||||
}
|
||||
|
||||
Player player = Bukkit.getPlayer(callback.getReceivingPlayerId());
|
||||
@ -162,7 +162,6 @@ public class Teleport extends MiniPlugin
|
||||
|
||||
private void generatePermissions()
|
||||
{
|
||||
|
||||
PermissionGroup.TRAINEE.setPermission(Perm.FIND_COMMAND, true, true);
|
||||
PermissionGroup.MC.setPermission(Perm.FIND_MOD_COMMAND, false, true);
|
||||
PermissionGroup.ADMIN.setPermission(Perm.FIND_MOD_COMMAND, true, true);
|
||||
@ -202,7 +201,7 @@ public class Teleport extends MiniPlugin
|
||||
UtilPlayer.message(player, F.main("Locate", C.mBody + "Failed to locate [" + C.mElem + target + C.mBody + "]."));
|
||||
}, 40L).getTaskId();
|
||||
|
||||
_failedRedisLocates.put(locate.getUUID(), Integer.valueOf(id));
|
||||
_failedRedisLocates.put(locate.getUUID(), id);
|
||||
}
|
||||
|
||||
public void locateRank(final Player sender, final PermissionGroup group)
|
||||
@ -221,7 +220,7 @@ public class Teleport extends MiniPlugin
|
||||
UtilPlayer.message(sender, F.main("Locate", "There are no members of that group online!"));
|
||||
}, 60L).getTaskId();
|
||||
|
||||
_failedRankLocates.put(locate.getUUID(), Integer.valueOf(id));
|
||||
_failedRankLocates.put(locate.getUUID(), id);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -39,8 +39,8 @@ public class ClansAdmin
|
||||
|
||||
private void generatePermissions()
|
||||
{
|
||||
|
||||
PermissionGroup.ADMIN.setPermission(Perm.USE_ADMIN_COMMANDS, true, true);
|
||||
PermissionGroup.CMOD.setPermission(Perm.USE_ADMIN_COMMANDS, false, true);
|
||||
}
|
||||
|
||||
public void command(Player caller, String[] args)
|
||||
@ -936,4 +936,4 @@ public class ClansAdmin
|
||||
//Inform
|
||||
UtilPlayer.message(caller, F.main("Clans Admin", "Territory Safe Zone: " + F.tf(claim.isSafe(caller.getLocation()))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ public class ObserverManager extends MiniPlugin
|
||||
|
||||
private void generatePermissions()
|
||||
{
|
||||
PermissionGroup.TRAINEE.setPermission(Perm.OBSERVE_COMMAND, false, true);
|
||||
PermissionGroup.TRAINEE.setPermission(Perm.OBSERVE_COMMAND, true, true);
|
||||
}
|
||||
|
||||
public void setObserver(Player player)
|
||||
@ -200,4 +200,4 @@ public class ObserverManager extends MiniPlugin
|
||||
{
|
||||
addCommand(new ObserverCommand(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +115,7 @@ import mineplex.core.projectile.ProjectileManager;
|
||||
import mineplex.core.punish.Punish;
|
||||
import mineplex.core.scoreboard.MineplexScoreboard;
|
||||
import mineplex.core.scoreboard.ScoreboardManager;
|
||||
import mineplex.core.scoreboard.TabListSorter;
|
||||
import mineplex.core.stats.StatsManager;
|
||||
import mineplex.core.status.ServerStatusManager;
|
||||
import mineplex.core.task.TaskManager;
|
||||
@ -275,7 +276,7 @@ public class HubManager extends MiniPlugin implements IChatMessageFormatter
|
||||
|
||||
new PersonalServerManager(plugin, _clientManager).setUseInterfaceItem(false);
|
||||
new CommunityManager(plugin, _clientManager);
|
||||
|
||||
require(TabListSorter.class);
|
||||
ScoreboardManager scoreboardManager = new ScoreboardManager(plugin)
|
||||
{
|
||||
@Override
|
||||
@ -1080,4 +1081,4 @@ public class HubManager extends MiniPlugin implements IChatMessageFormatter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ public class SalesAnnouncementRepository extends RepositoryBase
|
||||
{
|
||||
runAsync(() ->
|
||||
{
|
||||
executeUpdate(UPDATE_ANNOUNCEMENT_STATUS, new ColumnBoolean("enabled", data.isEnabled()), new ColumnInt("id", data.getId().intValue()));
|
||||
executeUpdate(UPDATE_ANNOUNCEMENT_STATUS, new ColumnBoolean("enabled", data.isEnabled()), new ColumnInt("id", data.getId()));
|
||||
if (after != null)
|
||||
{
|
||||
runSync(after);
|
||||
@ -165,7 +165,7 @@ public class SalesAnnouncementRepository extends RepositoryBase
|
||||
{
|
||||
runAsync(() ->
|
||||
{
|
||||
executeUpdate(DELETE_ANNOUNCEMENT, new ColumnInt("id", data.getId().intValue()));
|
||||
executeUpdate(DELETE_ANNOUNCEMENT, new ColumnInt("id", data.getId()));
|
||||
if (after != null)
|
||||
{
|
||||
runSync(after);
|
||||
|
@ -109,6 +109,7 @@ import mineplex.core.punish.Punish;
|
||||
import mineplex.core.quests.QuestManager;
|
||||
import mineplex.core.scoreboard.MineplexScoreboard;
|
||||
import mineplex.core.scoreboard.ScoreboardManager;
|
||||
import mineplex.core.scoreboard.TabListSorter;
|
||||
import mineplex.core.stats.StatsManager;
|
||||
import mineplex.core.status.ServerStatusManager;
|
||||
import mineplex.core.task.TaskManager;
|
||||
@ -308,6 +309,8 @@ public class HubManager extends MiniClientPlugin<HubClient> implements IChatMess
|
||||
|
||||
new TemporaryGemHuntersServerSender(_portal);
|
||||
|
||||
require(TabListSorter.class);
|
||||
|
||||
ScoreboardManager scoreboardManager = new ScoreboardManager(plugin)
|
||||
{
|
||||
@Override
|
||||
|
@ -18,7 +18,7 @@ public class LifetimeEternalCommand extends CommandBase<SalesPackageManager>
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
resetCommandCharge(caller);
|
||||
Bukkit.getServer().getPluginManager().callEvent(new PlayerCommandPreprocessEvent(caller, "/sales rank " + args[0] + " ETERNAL true"));
|
||||
Bukkit.getServer().getPluginManager().callEvent(new PlayerCommandPreprocessEvent(caller, "/sales rank " + args[0] + " ETERNAL"));
|
||||
|
||||
resetCommandCharge(caller);
|
||||
Bukkit.getServer().getPluginManager().callEvent(new PlayerCommandPreprocessEvent(caller, "/sales item " + args[0] + " 2 Item Mythical Chest"));
|
||||
@ -29,4 +29,4 @@ public class LifetimeEternalCommand extends CommandBase<SalesPackageManager>
|
||||
resetCommandCharge(caller);
|
||||
Bukkit.getServer().getPluginManager().callEvent(new PlayerCommandPreprocessEvent(caller, "/sales item " + args[0] + " 1 Item Omega Chest"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,9 +18,9 @@ public class LifetimeHeroCommand extends CommandBase<SalesPackageManager>
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
resetCommandCharge(caller);
|
||||
Bukkit.getServer().getPluginManager().callEvent(new PlayerCommandPreprocessEvent(caller, "/sales rank " + args[0] + " HERO true"));
|
||||
Bukkit.getServer().getPluginManager().callEvent(new PlayerCommandPreprocessEvent(caller, "/sales rank " + args[0] + " HERO"));
|
||||
|
||||
resetCommandCharge(caller);
|
||||
Bukkit.getServer().getPluginManager().callEvent(new PlayerCommandPreprocessEvent(caller, "/sales item " + args[0] + " 2 Item Mythical Chest"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,9 +18,9 @@ public class LifetimeLegendCommand extends CommandBase<SalesPackageManager>
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
resetCommandCharge(caller);
|
||||
Bukkit.getServer().getPluginManager().callEvent(new PlayerCommandPreprocessEvent(caller, "/sales rank " + args[0] + " LEGEND true"));
|
||||
Bukkit.getServer().getPluginManager().callEvent(new PlayerCommandPreprocessEvent(caller, "/sales rank " + args[0] + " LEGEND"));
|
||||
|
||||
resetCommandCharge(caller);
|
||||
Bukkit.getServer().getPluginManager().callEvent(new PlayerCommandPreprocessEvent(caller, "/sales item " + args[0] + " 3 Item Mythical Chest"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,9 +18,9 @@ public class LifetimeTitanCommand extends CommandBase<SalesPackageManager>
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
resetCommandCharge(caller);
|
||||
Bukkit.getServer().getPluginManager().callEvent(new PlayerCommandPreprocessEvent(caller, "/sales rank " + args[0] + " TITAN true"));
|
||||
Bukkit.getServer().getPluginManager().callEvent(new PlayerCommandPreprocessEvent(caller, "/sales rank " + args[0] + " TITAN"));
|
||||
|
||||
resetCommandCharge(caller);
|
||||
Bukkit.getServer().getPluginManager().callEvent(new PlayerCommandPreprocessEvent(caller, "/sales item " + args[0] + " 5 Item Mythical Chest"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,9 +18,9 @@ public class LifetimeUltraCommand extends CommandBase<SalesPackageManager>
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
resetCommandCharge(caller);
|
||||
Bukkit.getServer().getPluginManager().callEvent(new PlayerCommandPreprocessEvent(caller, "/sales rank " + args[0] + " ULTRA true"));
|
||||
Bukkit.getServer().getPluginManager().callEvent(new PlayerCommandPreprocessEvent(caller, "/sales rank " + args[0] + " ULTRA"));
|
||||
|
||||
resetCommandCharge(caller);
|
||||
Bukkit.getServer().getPluginManager().callEvent(new PlayerCommandPreprocessEvent(caller, "/sales item " + args[0] + " 1 Item Mythical Chest"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import mineplex.staffServer.salespackage.SalesPackageManager;
|
||||
|
||||
public class RankCommand extends CommandBase<SalesPackageManager>
|
||||
{
|
||||
private static final List<String> ACCEPTED_RANKS = Collections.unmodifiableList(Arrays.asList("player", "ultra", "hero", "legend", "titan", "eternal"));
|
||||
private static final List<String> ACCEPTED_RANKS = Collections.unmodifiableList(Arrays.asList("PLAYER", "ULTRA", "HERO", "LEGEND", "TITAN", "ETERNAL"));
|
||||
|
||||
public RankCommand(SalesPackageManager plugin)
|
||||
{
|
||||
@ -31,7 +31,7 @@ public class RankCommand extends CommandBase<SalesPackageManager>
|
||||
}
|
||||
|
||||
String playerName = args[0];
|
||||
String rank = args[1];
|
||||
String rank = args[1].toUpperCase();
|
||||
|
||||
if (ACCEPTED_RANKS.contains(rank))
|
||||
{
|
||||
@ -57,4 +57,4 @@ public class RankCommand extends CommandBase<SalesPackageManager>
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ public class DefaultRank extends SalesPackageBase
|
||||
|
||||
public void displayToAgent(Player agent, String playerName)
|
||||
{
|
||||
addButton(agent, "/sales rank " + playerName + " ALL false", " Default Rank.");
|
||||
addButton(agent, "/sales rank " + playerName + " PLAYER", " Default Rank.");
|
||||
agent.sendMessage(" ");
|
||||
addBackButton(agent, playerName);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ public class LifetimeEternal extends SalesPackageBase
|
||||
|
||||
public void displayToAgent(Player agent, String playerName)
|
||||
{
|
||||
addButton(agent, "/sales rank " + playerName + " ETERNAL true", "Lifetime Eternal.");
|
||||
addButton(agent, "/sales rank " + playerName + " ETERNAL", "Lifetime Eternal.");
|
||||
addButton(agent, "/sales item " + playerName + " 2 Item Mythical Chest", "2 Mythical Chests.");
|
||||
addButton(agent, "/sales item " + playerName + " 2 Item Illuminated Chest", "2 Illuminated Chests.");
|
||||
addButton(agent, "/sales item " + playerName + " 1 Item Omega Chest", "1 Omega Chest.");
|
||||
|
@ -13,7 +13,7 @@ public class LifetimeHero extends SalesPackageBase
|
||||
|
||||
public void displayToAgent(Player agent, String playerName)
|
||||
{
|
||||
addButton(agent, "/sales rank " + playerName + " HERO true", "Lifetime Hero.");
|
||||
addButton(agent, "/sales rank " + playerName + " HERO", "Lifetime Hero.");
|
||||
addButton(agent, "/sales item " + playerName + " 2 Item Mythical Chest", "2 Mythical Chests.");
|
||||
addButton(agent, "Apply All", "/sales lifetimehero " + playerName, "Apply all above.");
|
||||
agent.sendMessage(" ");
|
||||
|
@ -13,7 +13,7 @@ public class LifetimeLegend extends SalesPackageBase
|
||||
|
||||
public void displayToAgent(Player agent, String playerName)
|
||||
{
|
||||
addButton(agent, "/sales rank " + playerName + " LEGEND true", "Lifetime Legend.");
|
||||
addButton(agent, "/sales rank " + playerName + " LEGEND", "Lifetime Legend.");
|
||||
addButton(agent, "/sales item " + playerName + " 3 Item Mythical Chest", "3 Mythical Chests.");
|
||||
//addButton(agent, "/sales item " + playerName + " 1 Morph Wither Morph", "Gives Wither Morph.");
|
||||
//addButton(agent, "/sales item " + playerName + " 1 Pet Widder", "Gives Wither Pet.");
|
||||
|
@ -13,7 +13,7 @@ public class LifetimeTitan extends SalesPackageBase
|
||||
|
||||
public void displayToAgent(Player agent, String playerName)
|
||||
{
|
||||
addButton(agent, "/sales rank " + playerName + " TITAN true", "Lifetime Titan.");
|
||||
addButton(agent, "/sales rank " + playerName + " TITAN", "Lifetime Titan.");
|
||||
addButton(agent, "/sales item " + playerName + " 5 Item Mythical Chest", "5 Mythical Chests.");
|
||||
// addButton(agent, "/sales item " + playerName + " 1 Molten Snake", "Gives Molten Snake Mount.");
|
||||
// addButton(agent, "/sales item " + playerName + " 1 Elder Guardian Morph", "Gives Elder Guardian Morph.");
|
||||
|
@ -13,7 +13,7 @@ public class LifetimeUltra extends SalesPackageBase
|
||||
|
||||
public void displayToAgent(Player agent, String playerName)
|
||||
{
|
||||
addButton(agent, "/sales rank " + playerName + " ULTRA true", "Lifetime Ultra.");
|
||||
addButton(agent, "/sales rank " + playerName + " ULTRA", "Lifetime Ultra.");
|
||||
addButton(agent, "/sales item " + playerName + " 1 Item Mythical Chest", "1 Mythical Chest.");
|
||||
addButton(agent, "Apply All", "/sales lifetimeultra " + playerName, "Apply all above.");
|
||||
agent.sendMessage(" ");
|
||||
|
Loading…
Reference in New Issue
Block a user