package server.command;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import server.Group;
import server.Player;
import server.SyntaxException;
import server.Utils;
import server.token.TokenString;
public class GroupCommand extends Command {
private static final TokenString TS_GROUP_KICK = new TokenString("%N1 %v1/has/have/ kicked %Mc21/%x2/%n2/ out of the group.");
private static final LinkedHashSet<Invite> invites = new LinkedHashSet<Invite>();
public GroupCommand() {
super(CommandCategory.INTERACTION, "Grouping system.");
}
@Override
public void run(Player player) throws SyntaxException {
String subcmd = CommandProcessor.nextToken();
if (subcmd == null) {
throw new SyntaxException();
}
else if (subcmd.equals("invite")) {
String token = CommandProcessor.nextToken();
if (token == null || CommandProcessor.nextToken() != null) {
throw new SyntaxException();
}
Group group = player.getGroup();
if (group.getLeader() != player) {
player.sendText(true, "Only the group leader can invite people.");
return;
}
Player other = player.matchLocalPlayer(token);
if (other == null) {
player.sendText(true, "There's noone here by that name.");
return;
}
if (other == player) {
player.sendText(true, "You can't invite yourself.");
return;
}
Invite invite = new Invite(player, other);
invites.remove(invite);
invites.add(invite);
player.sendText(true, "You have invited " + other.getName(player, false) + " to join your group.");
other.sendText(true, Utils.capitalize(player.getName(other, false)) +
" has invited you to join " +
player.getPossessiveAdjective(other) +
" group. Use @10FGROUP JOIN " +
player.getId() +
"@ZZZ to accept " +
player.getPossessiveAdjective(other) +
" offer.");
}
else if (subcmd.equals("kick")) {
String token = CommandProcessor.nextToken();
if (token == null || CommandProcessor.nextToken() != null) {
throw new SyntaxException();
}
Group group = player.getGroup();
if (group.getLeader() != player) {
player.sendText(true, "Only the group leader can kick people out of the group.");
return;
}
Player other = player.getPlayerByNickname(token);
if (other == null) {
player.sendText(true, "Unknown player: " + token);
return;
}
if (other == player) {
player.sendText(true, "You can't kick yourself out of the group. " +
"Use @10FGROUP LEAVE@ZZZ if you want to leave the " +
"group.");
return;
}
if (group != other.getGroup()) {
player.sendText(true, "That player is not in your group.");
return;
}
group.sendText(null, null, null, null, TS_GROUP_KICK, null, player, other);
other.setGroup(new Group());
}
else if (subcmd.equals("join")) {
String token = CommandProcessor.nextToken();
if (token == null || CommandProcessor.nextToken() != null) {
throw new SyntaxException();
}
Player other = player.getPlayerByNickname(token);
if (other == null) {
player.sendText(true, "Unknown player: " + token);
return;
}
if (other == player) {
player.sendText(true, "You can't group with yourself.");
return;
}
purgeOldInvites();
boolean found = invites.remove(new Invite(other, player));
if (!found) {
player.sendText(
true, Utils.capitalize(other.getName(player, false)) +
" hasn't invited you to " +
other.getPossessiveAdjective(player) +
" group.");
return;
}
Group group = other.getGroup();
if (group.players().size() == 1) {
other.sendText(true, "You have formed the group.");
}
else {
for (Player target : group.players()) {
target.sendText(true, Utils.capitalize(player.getName(target, false)) +
" has joined the group.");
}
}
player.setGroup(group);
player.sendText(true, "You have joined the group.");
}
else if (subcmd.equals("leave")) {
if (CommandProcessor.nextToken() != null) {
throw new SyntaxException();
}
Group group = player.getGroup();
if (group.players().size() == 1) {
player.sendText(true, "You're not in a group.");
return;
}
player.setGroup(new Group());
player.sendText(true, "You have left the group.");
for (Player target : group.players()) {
target.sendText(
true, Utils.capitalize(player.getName(target, false)) +
" has left the group.");
}
}
else if (subcmd.equals("disband")) {
if (CommandProcessor.nextToken() != null) {
throw new SyntaxException();
}
Group group = player.getGroup();
if (group.players().size() == 1) {
player.sendText(true, "You're not in a group.");
return;
}
if (group.getLeader() != player) {
player.sendText(true, "Only the group leader can disband the group.");
return;
}
Collection<Player> players = new HashSet<Player>(group.players());
for (Player groupMember : players) {
if (groupMember == player) {
groupMember.sendText(true, "You have disbanded the group.");
}
else {
groupMember.sendText(
true, Utils.capitalize(player.getName(groupMember, false)) +
" has disbanded the group.");
}
groupMember.setGroup(new Group());
}
}
else {
throw new SyntaxException();
}
}
@Override
public String[] getSyntax(Player player) {
return new String[] {
"INVITE <player>",
"KICK <player>",
"JOIN <player>",
"LEAVE",
"DISBAND",
};
}
private static void purgeOldInvites() {
Iterator<Invite> iter = invites.iterator();
while (iter.hasNext()) {
Invite invite = iter.next();
if (invite.endTime < System.currentTimeMillis()) {
iter.remove();
}
}
}
private static class Invite {
public final long endTime =
System.currentTimeMillis() + 60000; public final Player invitor;
public final Player invitee;
public Invite(Player invitor, Player invitee) {
this.invitor = invitor;
this.invitee = invitee;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof Invite) {
Invite other = (Invite) obj;
return other.invitor == invitor &&
other.invitee == invitee;
}
return false;
}
@Override
public int hashCode() {
return invitor.getId() * 12349899 + invitee.getId();
}
}
}