mirror of
https://github.com/correl/mage.git
synced 2024-11-25 03:00:11 +00:00
* Some minor fixed and log changes.
This commit is contained in:
parent
9a21b55d39
commit
60cc3a7622
9 changed files with 90 additions and 46 deletions
|
@ -636,7 +636,8 @@ public class MageServerImpl implements MageServer {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
logger.error("table not found : " + tableId);
|
// this can happen if a game ends and a player quits XMage or a match nearly at the same time as the game ends
|
||||||
|
logger.trace("table not found : " + tableId);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1119,12 +1120,12 @@ public class MageServerImpl implements MageServer {
|
||||||
public void toggleActivation(final String sessionId, final String userName) throws MageException {
|
public void toggleActivation(final String sessionId, final String userName) throws MageException {
|
||||||
execute("toggleActivation", sessionId, ()
|
execute("toggleActivation", sessionId, ()
|
||||||
-> UserManager.instance.getUserByName(userName).ifPresent(user
|
-> UserManager.instance.getUserByName(userName).ifPresent(user
|
||||||
-> {
|
-> {
|
||||||
user.setActive(!user.isActive());
|
user.setActive(!user.isActive());
|
||||||
if (!user.isActive() && user.isConnected()) {
|
if (!user.isActive() && user.isConnected()) {
|
||||||
SessionManager.instance.disconnectUser(sessionId, user.getSessionId());
|
SessionManager.instance.disconnectUser(sessionId, user.getSessionId());
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1159,8 +1160,8 @@ public class MageServerImpl implements MageServer {
|
||||||
if (title != null && message != null) {
|
if (title != null && message != null) {
|
||||||
execute("sendFeedbackMessage", sessionId, ()
|
execute("sendFeedbackMessage", sessionId, ()
|
||||||
-> SessionManager.instance.getSession(sessionId).ifPresent(
|
-> SessionManager.instance.getSession(sessionId).ifPresent(
|
||||||
session -> FeedbackServiceImpl.instance.feedback(username, title, type, message, email, session.getHost())
|
session -> FeedbackServiceImpl.instance.feedback(username, title, type, message, email, session.getHost())
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,11 @@
|
||||||
*/
|
*/
|
||||||
package mage.server;
|
package mage.server;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import mage.MageException;
|
import mage.MageException;
|
||||||
import mage.constants.Constants;
|
import mage.constants.Constants;
|
||||||
import mage.interfaces.callback.ClientCallback;
|
import mage.interfaces.callback.ClientCallback;
|
||||||
|
@ -44,12 +49,6 @@ import org.jboss.remoting.callback.Callback;
|
||||||
import org.jboss.remoting.callback.HandleCallbackException;
|
import org.jboss.remoting.callback.HandleCallbackException;
|
||||||
import org.jboss.remoting.callback.InvokerCallbackHandler;
|
import org.jboss.remoting.callback.InvokerCallbackHandler;
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
*/
|
*/
|
||||||
|
@ -218,8 +217,8 @@ public class Session {
|
||||||
if (authorizedUser.lockedUntil.compareTo(Calendar.getInstance().getTime()) > 0) {
|
if (authorizedUser.lockedUntil.compareTo(Calendar.getInstance().getTime()) > 0) {
|
||||||
return "Your profile is deactivated until " + SystemUtil.dateFormat.format(authorizedUser.lockedUntil);
|
return "Your profile is deactivated until " + SystemUtil.dateFormat.format(authorizedUser.lockedUntil);
|
||||||
} else {
|
} else {
|
||||||
UserManager.instance.createUser(userName, host, authorizedUser).ifPresent(user ->
|
UserManager.instance.createUser(userName, host, authorizedUser).ifPresent(user
|
||||||
user.setLockedUntil(null)
|
-> user.setLockedUntil(null)
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -263,7 +262,6 @@ public class Session {
|
||||||
ChatManager.instance.sendReconnectMessage(userId);
|
ChatManager.instance.sendReconnectMessage(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -337,7 +335,7 @@ public class Session {
|
||||||
lockSet = true;
|
lockSet = true;
|
||||||
logger.debug("SESSION LOCK SET sessionId: " + sessionId);
|
logger.debug("SESSION LOCK SET sessionId: " + sessionId);
|
||||||
} else {
|
} else {
|
||||||
logger.error("CAN'T GET LOCK - userId: " + userId + " hold count: " + lock.getHoldCount());
|
logger.warn("CAN'T GET LOCK - userId: " + userId + " hold count: " + lock.getHoldCount());
|
||||||
}
|
}
|
||||||
Optional<User> _user = UserManager.instance.getUser(userId);
|
Optional<User> _user = UserManager.instance.getUser(userId);
|
||||||
if (!_user.isPresent()) {
|
if (!_user.isPresent()) {
|
||||||
|
@ -393,7 +391,7 @@ public class Session {
|
||||||
call.setMessageId(messageId++);
|
call.setMessageId(messageId++);
|
||||||
callbackHandler.handleCallbackOneway(new Callback(call));
|
callbackHandler.handleCallbackOneway(new Callback(call));
|
||||||
} catch (HandleCallbackException ex) {
|
} catch (HandleCallbackException ex) {
|
||||||
ex.printStackTrace();
|
// ex.printStackTrace();
|
||||||
UserManager.instance.getUser(userId).ifPresent(user -> {
|
UserManager.instance.getUser(userId).ifPresent(user -> {
|
||||||
logger.warn("SESSION CALLBACK EXCEPTION - " + user.getName() + " userId " + userId);
|
logger.warn("SESSION CALLBACK EXCEPTION - " + user.getName() + " userId " + userId);
|
||||||
logger.warn(" - method: " + call.getMethod());
|
logger.warn(" - method: " + call.getMethod());
|
||||||
|
|
|
@ -144,8 +144,10 @@ public enum SessionManager {
|
||||||
case LostConnection: // user lost connection - session expires countdaoun starts
|
case LostConnection: // user lost connection - session expires countdaoun starts
|
||||||
session.userLostConnection();
|
session.userLostConnection();
|
||||||
break;
|
break;
|
||||||
|
case ConnectingOtherInstance:
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
logger.error("endSession: unexpected reason " + reason.toString() + " - sessionId: " + sessionId);
|
logger.trace("endSession: unexpected reason " + reason.toString() + " - sessionId: " + sessionId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sessions.remove(sessionId);
|
sessions.remove(sessionId);
|
||||||
|
|
|
@ -50,6 +50,7 @@ import mage.game.events.ZoneChangeEvent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.common.TargetCardInYourGraveyard;
|
import mage.target.common.TargetCardInYourGraveyard;
|
||||||
import mage.target.targetpointer.FixedTarget;
|
import mage.target.targetpointer.FixedTarget;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -64,7 +65,7 @@ public class TorrentialGearhulk extends CardImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
public TorrentialGearhulk(UUID ownerId, CardSetInfo setInfo) {
|
public TorrentialGearhulk(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}{U}{U}");
|
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}{U}{U}");
|
||||||
this.subtype.add("Construct");
|
this.subtype.add("Construct");
|
||||||
this.power = new MageInt(5);
|
this.power = new MageInt(5);
|
||||||
this.toughness = new MageInt(6);
|
this.toughness = new MageInt(6);
|
||||||
|
@ -111,7 +112,7 @@ class TorrentialGearhulkEffect extends OneShotEffect {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
Card card = game.getCard(this.getTargetPointer().getFirst(game, source));
|
Card card = game.getCard(this.getTargetPointer().getFirst(game, source));
|
||||||
if (card != null) {
|
if (card != null && card.getSpellAbility() != null) {
|
||||||
if (controller.chooseUse(outcome, "Cast " + card.getLogName() + '?', source, game)) {
|
if (controller.chooseUse(outcome, "Cast " + card.getLogName() + '?', source, game)) {
|
||||||
if (controller.cast(card.getSpellAbility(), game, true)) {
|
if (controller.cast(card.getSpellAbility(), game, true)) {
|
||||||
ContinuousEffect effect = new TorrentialGearhulkReplacementEffect(card.getId());
|
ContinuousEffect effect = new TorrentialGearhulkReplacementEffect(card.getId());
|
||||||
|
@ -119,6 +120,9 @@ class TorrentialGearhulkEffect extends OneShotEffect {
|
||||||
game.addEffect(effect, source);
|
game.addEffect(effect, source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Logger.getLogger(TorrentialGearhulkEffect.class).error("Torrential Gearhulk - Instant card without spellAbility : " + card.getName());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,4 +108,37 @@ public class EndTurnEffectTest extends CardTestPlayerBase {
|
||||||
assertHandCount(playerB, 0);
|
assertHandCount(playerB, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test to remove a Aftermath card from spell
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSpellAftermath() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||||
|
// Insult Sorcery {2}{R}
|
||||||
|
// Damage can't be prevented this turn. If a source you control would deal damage this turn, it deals double that damage instead.
|
||||||
|
// Injury Sorcery {2}{R}
|
||||||
|
// Aftermath (Cast this spell only from your graveyard. Then exile it.)
|
||||||
|
// Injury deals 2 damage to target creature and 2 damage to target player.
|
||||||
|
addCard(Zone.GRAVEYARD, playerA, "Insult // Injury");
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 3);
|
||||||
|
// End the turn.
|
||||||
|
// At the beginning of your next end step, you lose the game.
|
||||||
|
addCard(Zone.HAND, playerB, "Glorious End"); //Instant {2}{R}
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Injury", "Silvercoat Lion");
|
||||||
|
addTarget(playerA, playerB);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Glorious End", NO_TARGET, "Injury");
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertExileCount(playerA, "Insult // Injury", 1);
|
||||||
|
assertGraveyardCount(playerB, "Glorious End", 0);
|
||||||
|
assertHandCount(playerA, 0);
|
||||||
|
assertHandCount(playerB, 0);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
*/
|
*/
|
||||||
package mage.abilities.common;
|
package mage.abilities.common;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.ActivatedAbilityImpl;
|
import mage.abilities.ActivatedAbilityImpl;
|
||||||
|
@ -144,14 +145,16 @@ class LicidContinuousEffect extends ContinuousEffectImpl {
|
||||||
licid.getSubtype(game).add("Aura");
|
licid.getSubtype(game).add("Aura");
|
||||||
break;
|
break;
|
||||||
case AbilityAddingRemovingEffects_6:
|
case AbilityAddingRemovingEffects_6:
|
||||||
|
ArrayList<Ability> toRemove = new ArrayList<>();
|
||||||
for (Ability ability : licid.getAbilities(game)) {
|
for (Ability ability : licid.getAbilities(game)) {
|
||||||
for (Effect effect : ability.getEffects()) {
|
for (Effect effect : ability.getEffects()) {
|
||||||
if (effect instanceof LicidEffect) {
|
if (effect instanceof LicidEffect) {
|
||||||
licid.getAbilities(game).remove(ability);
|
toRemove.add(ability);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
licid.getAbilities(game).removeAll(toRemove);
|
||||||
Ability ability = new EnchantAbility("creature");
|
Ability ability = new EnchantAbility("creature");
|
||||||
ability.setRuleAtTheTop(true);
|
ability.setRuleAtTheTop(true);
|
||||||
licid.addAbility(ability, source.getSourceId(), game);
|
licid.addAbility(ability, source.getSourceId(), game);
|
||||||
|
|
|
@ -1218,7 +1218,10 @@ public class ContinuousEffects implements Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.error("Replacement effect without ability: " + entry.getKey().toString());
|
if (!(entry.getKey() instanceof AuraReplacementEffect)
|
||||||
|
&& !(entry.getKey() instanceof PlaneswalkerRedirectionEffect)) {
|
||||||
|
logger.error("Replacement effect without ability: " + entry.getKey().toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return texts;
|
return texts;
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
* authors and should not be interpreted as representing official policies, either expressed
|
* authors and should not be interpreted as representing official policies, either expressed
|
||||||
* or implied, of BetaSteward_at_googlemail.com.
|
* or implied, of BetaSteward_at_googlemail.com.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package mage.abilities.effects.common.counter;
|
package mage.abilities.effects.common.counter;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -47,8 +46,8 @@ import mage.util.CardUtil;
|
||||||
*
|
*
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class RemoveCounterTargetEffect extends OneShotEffect {
|
public class RemoveCounterTargetEffect extends OneShotEffect {
|
||||||
|
|
||||||
private final Counter counter;
|
private final Counter counter;
|
||||||
|
|
||||||
public RemoveCounterTargetEffect() {
|
public RemoveCounterTargetEffect() {
|
||||||
|
@ -69,23 +68,25 @@ public class RemoveCounterTargetEffect extends OneShotEffect {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
Permanent p = game.getPermanent(targetPointer.getFirst(game, source));
|
Permanent p = game.getPermanent(targetPointer.getFirst(game, source));
|
||||||
if(p != null) {
|
if (p != null) {
|
||||||
Counter toRemove = (counter == null ? selectCounterType(game, source, p) : counter);
|
Counter toRemove = (counter == null ? selectCounterType(game, source, p) : counter);
|
||||||
if(toRemove != null && p.getCounters(game).getCount(toRemove.getName()) >= toRemove.getCount()) {
|
if (toRemove != null && p.getCounters(game).getCount(toRemove.getName()) >= toRemove.getCount()) {
|
||||||
p.removeCounters(toRemove.getName(), toRemove.getCount(), game);
|
p.removeCounters(toRemove.getName(), toRemove.getCount(), game);
|
||||||
if(!game.isSimulation())
|
if (!game.isSimulation()) {
|
||||||
game.informPlayers("Removed " + toRemove.getCount() + ' ' + toRemove.getName()
|
game.informPlayers("Removed " + toRemove.getCount() + ' ' + toRemove.getName()
|
||||||
+ " counter from " + p.getName());
|
+ " counter from " + p.getName());
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Card c = game.getCard(targetPointer.getFirst(game, source));
|
Card c = game.getCard(targetPointer.getFirst(game, source));
|
||||||
if (c != null && counter != null && c.getCounters(game).getCount(counter.getName()) >= counter.getCount()) {
|
if (c != null && counter != null && c.getCounters(game).getCount(counter.getName()) >= counter.getCount()) {
|
||||||
c.removeCounters(counter.getName(), counter.getCount(), game);
|
c.removeCounters(counter.getName(), counter.getCount(), game);
|
||||||
if (!game.isSimulation())
|
if (!game.isSimulation()) {
|
||||||
game.informPlayers(new StringBuilder("Removed ").append(counter.getCount()).append(' ').append(counter.getName())
|
game.informPlayers(new StringBuilder("Removed ").append(counter.getCount()).append(' ').append(counter.getName())
|
||||||
.append(" counter from ").append(c.getName())
|
.append(" counter from ").append(c.getName())
|
||||||
.append(" (").append(c.getCounters(game).getCount(counter.getName())).append(" left)").toString());
|
.append(" (").append(c.getCounters(game).getCount(counter.getName())).append(" left)").toString());
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -93,12 +94,12 @@ public class RemoveCounterTargetEffect extends OneShotEffect {
|
||||||
|
|
||||||
private Counter selectCounterType(Game game, Ability source, Permanent permanent) {
|
private Counter selectCounterType(Game game, Ability source, Permanent permanent) {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
if(controller != null && !permanent.getCounters(game).isEmpty()) {
|
if (controller != null && !permanent.getCounters(game).isEmpty()) {
|
||||||
String counterName = null;
|
String counterName = null;
|
||||||
if(permanent.getCounters(game).size() > 1) {
|
if (permanent.getCounters(game).size() > 1) {
|
||||||
Choice choice = new ChoiceImpl(true);
|
Choice choice = new ChoiceImpl(true);
|
||||||
Set<String> choices = new HashSet<>();
|
Set<String> choices = new HashSet<>();
|
||||||
for(Counter counter : permanent.getCounters(game).values()) {
|
for (Counter counter : permanent.getCounters(game).values()) {
|
||||||
if (permanent.getCounters(game).getCount(counter.getName()) > 0) {
|
if (permanent.getCounters(game).getCount(counter.getName()) > 0) {
|
||||||
choices.add(counter.getName());
|
choices.add(counter.getName());
|
||||||
}
|
}
|
||||||
|
@ -108,8 +109,8 @@ public class RemoveCounterTargetEffect extends OneShotEffect {
|
||||||
controller.choose(Outcome.Detriment, choice, game);
|
controller.choose(Outcome.Detriment, choice, game);
|
||||||
counterName = choice.getChoice();
|
counterName = choice.getChoice();
|
||||||
} else {
|
} else {
|
||||||
for(Counter counter : permanent.getCounters(game).values()) {
|
for (Counter counter : permanent.getCounters(game).values()) {
|
||||||
if(counter.getCount() > 0) {
|
if (counter.getCount() > 0) {
|
||||||
counterName = counter.getName();
|
counterName = counter.getName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,14 +132,13 @@ public class RemoveCounterTargetEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
|
|
||||||
String text = "remove ";
|
String text = "remove ";
|
||||||
if(counter == null) {
|
if (counter == null) {
|
||||||
text += "a counter";
|
text += "a counter";
|
||||||
|
} else {
|
||||||
|
text += CardUtil.numberToText(counter.getCount(), "a") + ' ' + counter.getName();
|
||||||
|
text += counter.getCount() > 1 ? " counters" : " counter";
|
||||||
}
|
}
|
||||||
else {
|
text += " from target " + (mode.getTargets().isEmpty() ? " object" : mode.getTargets().get(0).getTargetName());
|
||||||
text += CardUtil.numberToText(counter.getCount(), "a") + ' ' + counter.getName();
|
|
||||||
text += counter.getCount() > 1 ? " counters" : " counter";
|
|
||||||
}
|
|
||||||
text += " from target " + mode.getTargets().get(0).getTargetName();
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,7 +276,7 @@ public class Turn implements Serializable {
|
||||||
|
|
||||||
setEndTurnRequested(true);
|
setEndTurnRequested(true);
|
||||||
|
|
||||||
// 1) All spells and abilities on the stack are exiled. This includes Time Stop, though it will continue to resolve.
|
// 1) All spells and abilities on the stack are exiled. This includes (e.g.) Time Stop, though it will continue to resolve.
|
||||||
// It also includes spells and abilities that can't be countered.
|
// It also includes spells and abilities that can't be countered.
|
||||||
while (!game.getStack().isEmpty()) {
|
while (!game.getStack().isEmpty()) {
|
||||||
StackObject stackObject = game.getStack().peekFirst();
|
StackObject stackObject = game.getStack().peekFirst();
|
||||||
|
|
Loading…
Reference in a new issue