Skip to content

Commit

Permalink
introduce MyStatusCommandProcessor & MyBattleStatusCommandProcessor
Browse files Browse the repository at this point in the history
  • Loading branch information
hoijui committed Jan 19, 2011
1 parent 9be954a commit 3df7fa3
Show file tree
Hide file tree
Showing 4 changed files with 232 additions and 127 deletions.
127 changes: 0 additions & 127 deletions src/main/java/com/springrts/tasserver/TASServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -500,133 +500,6 @@ public boolean tryToExecCommand(String command, Client client) {
if (response.substring(0, 12).toUpperCase().equals("SERVERMSGBOX")) {
context.getClients().killClient(client);
}
} else if (commands[0].equals("MYBATTLESTATUS")) {
if (commands.length != 3) {
return false;
}
if (client.getAccount().getAccess().compareTo(Account.Access.NORMAL) < 0) {
return false;
}

if (client.getBattleID() == Battle.NO_BATTLE_ID) {
return false;
}

Battle bat = context.getBattles().getBattleByID(client.getBattleID());
if (bat == null) {
return false;
}

int newTeamColor;
try {
newTeamColor = Integer.parseInt(commands[2]);
} catch (NumberFormatException e) {
return false;
}
client.setTeamColor(newTeamColor);

int newStatus;
try {
newStatus = Integer.parseInt(commands[1]);
} catch (NumberFormatException e) {
return false;
}
// update new battle status. Note: we ignore handicap value as it can be changed only by founder with HANDICAP command!
client.setBattleStatus(Misc.setHandicapOfBattleStatus(newStatus, Misc.getHandicapFromBattleStatus(client.getBattleStatus())));

// if game is full or game type is "battle replay", force player's mode to spectator:
if ((bat.getClientsSize() + 1 - bat.spectatorCount() > bat.getMaxPlayers()) || (bat.getType() == 1)) {
client.setBattleStatus(Misc.setModeOfBattleStatus(client.getBattleStatus(), 0));
}
// if player has chosen team number which is already used by some other player/bot,
// force his ally number and team color to be the same as of that player/bot:
if (bat.getFounder() != client) {
if ((Misc.getTeamNoFromBattleStatus(bat.getFounder().getBattleStatus()) == Misc.getTeamNoFromBattleStatus(client.getBattleStatus())) && (Misc.getModeFromBattleStatus(bat.getFounder().getBattleStatus()) != 0)) {
client.setBattleStatus(Misc.setAllyNoOfBattleStatus(client.getBattleStatus(), Misc.getAllyNoFromBattleStatus(bat.getFounder().getBattleStatus())));
client.setTeamColor(bat.getFounder().getTeamColor());
}
}
for (int i = 0; i < bat.getClientsSize(); i++) {
if (bat.getClient(i) != client) {
if ((Misc.getTeamNoFromBattleStatus(bat.getClient(i).getBattleStatus()) == Misc.getTeamNoFromBattleStatus(client.getBattleStatus())) && (Misc.getModeFromBattleStatus(bat.getClient(i).getBattleStatus()) != 0)) {
client.setBattleStatus(Misc.setAllyNoOfBattleStatus(client.getBattleStatus(), Misc.getAllyNoFromBattleStatus(bat.getClient(i).getBattleStatus())));
client.setTeamColor(bat.getClient(i).getTeamColor());
break;
}
}
}
for (int i = 0; i < bat.getBotsSize(); i++) {
if (Misc.getTeamNoFromBattleStatus(bat.getBot(i).getBattleStatus()) == Misc.getTeamNoFromBattleStatus(client.getBattleStatus())) {
client.setBattleStatus(Misc.setAllyNoOfBattleStatus(client.getBattleStatus(), Misc.getAllyNoFromBattleStatus(bat.getBot(i).getBattleStatus())));
client.setTeamColor(bat.getBot(i).getTeamColor());
break;
}
}

bat.notifyClientsOfBattleStatus(client);
} else if (commands[0].equals("MYSTATUS")) {
if (commands.length != 2) {
return false;
}
if (client.getAccount().getAccess().compareTo(Account.Access.NORMAL) < 0) {
return false;
}

int newStatus;
try {
newStatus = Integer.parseInt(commands[1]);
} catch (NumberFormatException e) {
return false;
}

// we must preserve rank bits, access bit and bot mode bit (client is not allowed to change them himself):
int tmp = client.getRankFromStatus();
boolean tmp2 = client.getInGameFromStatus();
boolean tmp3 = client.getAccessFromStatus();
boolean tmp4 = client.getBotModeFromStatus();

client.setStatus(newStatus);

client.setRankToStatus(tmp);
client.setAccessToStatus(tmp3);
client.setBotModeToStatus(tmp4);

if (client.getInGameFromStatus() != tmp2) {
// user changed his in-game status.
if (tmp2 == false) { // client just entered game
Battle bat = context.getBattles().getBattleByID(client.getBattleID());
if ((bat != null) && (bat.getClientsSize() > 0)) {
client.setInGameTime(System.currentTimeMillis());
} else {
client.setInGameTime(0); // we won't update clients who play by themselves (or with bots), since some try to exploit the system by leaving computer alone in-battle for hours to increase their ranks
} // check if client is a battle host using "hole punching" technique:
if ((bat != null) && (bat.getFounder() == client) && (bat.getNatType() == 1)) {
// tell clients to replace battle port with founder's public UDP source port:
bat.sendToAllExceptFounder(new StringBuilder("HOSTPORT ").append(client.getUdpSourcePort()).toString());
}
} else { // back from game
if (client.getInGameTime() != 0) {
// We will not update clients that play
// by themselves (or with bots only),
// since some try to exploit the system
// by leaving their computer alone in-battle
// for hours, to increase their ranks.
long diffMins = (System.currentTimeMillis() - client.getInGameTime()) / 60000;
boolean rankChanged = client.getAccount().addMinsToInGameTime(diffMins);
if (rankChanged) {
client.setRankToStatus(client.getAccount().getRank().ordinal());
}
final boolean mergeOk = context.getAccountsService().mergeAccountChanges( client.getAccount(), client.getAccount().getName());
if (!mergeOk) {
// as this is no serious problem, only log a message
s_log.warn(new StringBuilder("Failed updating users in-game-time in persistent storage: ")
.append(client.getAccount().getName()).toString());
return false;
}
}
}
}
context.getClients().notifyClientsOfNewClientStatus(client);
} else if (commands[0].equals("UPDATEBATTLEINFO")) {
if (commands.length < 5) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@
import com.springrts.tasserver.commands.impl.MemoryAvailableCommandProcessor;
import com.springrts.tasserver.commands.impl.MuteCommandProcessor;
import com.springrts.tasserver.commands.impl.MuteListCommandProcessor;
import com.springrts.tasserver.commands.impl.MyBattleStatusCommandProcessor;
import com.springrts.tasserver.commands.impl.MyStatusCommandProcessor;
import com.springrts.tasserver.commands.impl.OpenBattleCommandProcessor;
import com.springrts.tasserver.commands.impl.PingCommandProcessor;
import com.springrts.tasserver.commands.impl.ReInitializeIp2CountryCommandProcessor;
Expand Down Expand Up @@ -234,6 +236,8 @@ public void init() {
commandProcessorClasses.add(JoinBattleAcceptCommandProcessor.class);
commandProcessorClasses.add(JoinBattleDenyCommandProcessor.class);
commandProcessorClasses.add(LeaveBattleCommandProcessor.class);
commandProcessorClasses.add(MyBattleStatusCommandProcessor.class);
commandProcessorClasses.add(MyStatusCommandProcessor.class);

try {
load(commandProcessorClasses);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
Copyright (c) 2010 Robin Vobruba <robin.vobruba@derisk.ch>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.springrts.tasserver.commands.impl;


import com.springrts.tasserver.Account;
import com.springrts.tasserver.Battle;
import com.springrts.tasserver.Client;
import com.springrts.tasserver.Misc;
import com.springrts.tasserver.commands.AbstractCommandProcessor;
import com.springrts.tasserver.commands.CommandProcessingException;
import com.springrts.tasserver.commands.SupportedCommand;
import java.util.List;

/**
* Sent by a client to the server telling him his status in the battle changed.
* @author hoijui
*/
@SupportedCommand("MYBATTLESTATUS")
public class MyBattleStatusCommandProcessor extends AbstractCommandProcessor {

public MyBattleStatusCommandProcessor() {
super(2, 2, Account.Access.NORMAL);
}

@Override
public boolean process(Client client, List<String> args)
throws CommandProcessingException
{
boolean checksOk = super.process(client, args);
if (!checksOk) {
return false;
}

if (client.getBattleID() == Battle.NO_BATTLE_ID) {
return false;
}

Battle bat = getContext().getBattles().getBattleByID(client.getBattleID());
if (bat == null) {
return false;
}

String newStatusStr = args.get(0);
String teamColorStr = args.get(1);

int newStatus;
try {
newStatus = Integer.parseInt(newStatusStr);
} catch (NumberFormatException ex) {
return false;
}
// update new battle status. Note: we ignore handicap value as it can be changed only by founder with HANDICAP command!
client.setBattleStatus(Misc.setHandicapOfBattleStatus(newStatus, Misc.getHandicapFromBattleStatus(client.getBattleStatus())));

int newTeamColor;
try {
newTeamColor = Integer.parseInt(teamColorStr);
} catch (NumberFormatException e) {
return false;
}
client.setTeamColor(newTeamColor);

// if game is full or game type is "battle replay", force player's mode to spectator:
if ((bat.getClientsSize() + 1 - bat.spectatorCount() > bat.getMaxPlayers()) || (bat.getType() == 1)) {
client.setBattleStatus(Misc.setModeOfBattleStatus(client.getBattleStatus(), 0));
}
// if player has chosen team number which is already used by some other player/bot,
// force his ally number and team color to be the same as of that player/bot:
if (bat.getFounder() != client) {
if ((Misc.getTeamNoFromBattleStatus(bat.getFounder().getBattleStatus()) == Misc.getTeamNoFromBattleStatus(client.getBattleStatus())) && (Misc.getModeFromBattleStatus(bat.getFounder().getBattleStatus()) != 0)) {
client.setBattleStatus(Misc.setAllyNoOfBattleStatus(client.getBattleStatus(), Misc.getAllyNoFromBattleStatus(bat.getFounder().getBattleStatus())));
client.setTeamColor(bat.getFounder().getTeamColor());
}
}
for (int i = 0; i < bat.getClientsSize(); i++) {
if (bat.getClient(i) != client) {
if ((Misc.getTeamNoFromBattleStatus(bat.getClient(i).getBattleStatus()) == Misc.getTeamNoFromBattleStatus(client.getBattleStatus())) && (Misc.getModeFromBattleStatus(bat.getClient(i).getBattleStatus()) != 0)) {
client.setBattleStatus(Misc.setAllyNoOfBattleStatus(client.getBattleStatus(), Misc.getAllyNoFromBattleStatus(bat.getClient(i).getBattleStatus())));
client.setTeamColor(bat.getClient(i).getTeamColor());
break;
}
}
}
for (int i = 0; i < bat.getBotsSize(); i++) {
if (Misc.getTeamNoFromBattleStatus(bat.getBot(i).getBattleStatus()) == Misc.getTeamNoFromBattleStatus(client.getBattleStatus())) {
client.setBattleStatus(Misc.setAllyNoOfBattleStatus(client.getBattleStatus(), Misc.getAllyNoFromBattleStatus(bat.getBot(i).getBattleStatus())));
client.setTeamColor(bat.getBot(i).getTeamColor());
break;
}
}

bat.notifyClientsOfBattleStatus(client);

return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
Copyright (c) 2010 Robin Vobruba <robin.vobruba@derisk.ch>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.springrts.tasserver.commands.impl;


import com.springrts.tasserver.Account;
import com.springrts.tasserver.Battle;
import com.springrts.tasserver.Client;
import com.springrts.tasserver.commands.AbstractCommandProcessor;
import com.springrts.tasserver.commands.CommandProcessingException;
import com.springrts.tasserver.commands.SupportedCommand;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* Sent by client to server telling him his status changed.
* To figure out if battle is "in-game", client must check in-game status of the
* host.
* @author hoijui
*/
@SupportedCommand("MYSTATUS")
public class MyStatusCommandProcessor extends AbstractCommandProcessor {

private static final Log s_log = LogFactory.getLog(MyStatusCommandProcessor.class);

public MyStatusCommandProcessor() {
super(1, 1, Account.Access.NORMAL);
}

@Override
public boolean process(Client client, List<String> args)
throws CommandProcessingException
{
boolean checksOk = super.process(client, args);
if (!checksOk) {
return false;
}

String newStatusStr = args.get(0);

int newStatus;
try {
newStatus = Integer.parseInt(newStatusStr);
} catch (NumberFormatException e) {
return false;
}

// we must preserve rank bits, access bit and bot mode bit (client is not allowed to change them himself):
int tmp = client.getRankFromStatus();
boolean tmp2 = client.getInGameFromStatus();
boolean tmp3 = client.getAccessFromStatus();
boolean tmp4 = client.getBotModeFromStatus();

client.setStatus(newStatus);

client.setRankToStatus(tmp);
client.setAccessToStatus(tmp3);
client.setBotModeToStatus(tmp4);

if (client.getInGameFromStatus() != tmp2) {
// user changed his in-game status.
if (tmp2 == false) { // client just entered game
Battle bat = getContext().getBattles().getBattleByID(client.getBattleID());
if ((bat != null) && (bat.getClientsSize() > 0)) {
client.setInGameTime(System.currentTimeMillis());
} else {
client.setInGameTime(0); // we won't update clients who play by themselves (or with bots), since some try to exploit the system by leaving computer alone in-battle for hours to increase their ranks
} // check if client is a battle host using "hole punching" technique:
if ((bat != null) && (bat.getFounder() == client) && (bat.getNatType() == 1)) {
// tell clients to replace battle port with founder's public UDP source port:
bat.sendToAllExceptFounder(new StringBuilder("HOSTPORT ").append(client.getUdpSourcePort()).toString());
}
} else { // back from game
if (client.getInGameTime() != 0) {
// We will not update clients that play
// by themselves (or with bots only),
// since some try to exploit the system
// by leaving their computer alone in-battle
// for hours, to increase their ranks.
long diffMins = (System.currentTimeMillis() - client.getInGameTime()) / 60000;
boolean rankChanged = client.getAccount().addMinsToInGameTime(diffMins);
if (rankChanged) {
client.setRankToStatus(client.getAccount().getRank().ordinal());
}
final boolean mergeOk = getContext().getAccountsService().mergeAccountChanges( client.getAccount(), client.getAccount().getName());
if (!mergeOk) {
// as this is no serious problem, only log a message
s_log.warn(new StringBuilder("Failed updating users in-game-time in persistent storage: ")
.append(client.getAccount().getName()).toString());
return false;
}
}
}
}
getContext().getClients().notifyClientsOfNewClientStatus(client);

return true;
}
}

0 comments on commit 3df7fa3

Please sign in to comment.