package ipcards.net;
import ipcards.events.*;
import ipcards.*;
import java.awt.Point;
import java.util.LinkedList;
import java.util.Vector;
/**
* Models player actions on the server side for a single {@link Client}.
*
* @author Ricky Vincent
*/
public class ServerModel implements PlayerActionListener, PlayerActionPerformer {
private static final char SEE = 0;
private static final char CONTROL = 1;
private static final char PERMISSION = 2;
/**
* The {@link Table} this client is at.
*/
private Table table;
/**
* Cards held by this client
*/
private CardSet heldCards = new CardSet();
/**
* cards locally flipped by this client
*/
private CardSet locallyFlippedCards = new CardSet();
/**
* Reference to the {@link Client} object
*/
private Client client;
/**
* If a game needs to add more decks due to too many people for one deck, this will indicate how many extra decks are needed
*/
public int addDecks = 0;
/**
* Constructs a ServerModel object.
*
* @param table The {@link Table} this client is at.
*/
public ServerModel (Table table, Client client) {
this.table = table;
this.table.sModel = this;
this.client = client;
}
/**
* Flips all of the held cards.
*/
public CardSet flip() {
CardSet newSet = new CardSet();
if(heldCards.isEmpty())
return newSet;
for (Card card: heldCards) {
if(card.permissionQuery(client.thisplayer, SEE)) {
card.toggleFaceUp();
newSet.add(card);
}
}
return newSet;
}
public CardSet setFaceUp() {
CardSet newSet = new CardSet();
if(heldCards.isEmpty())
return newSet;
for (Card card: heldCards) {
if(card.permissionQuery(client.thisplayer, CONTROL)) {
card.setFaceUp();
newSet.add(card);
}
}
return newSet;
}
public CardSet setFaceDown() {
CardSet newSet = new CardSet();
if(heldCards.isEmpty())
return newSet;
for (Card card: heldCards) {
if(card.permissionQuery(client.thisplayer, CONTROL)) {
card.setFaceDown();
newSet.add(card);
}
}
return newSet;
}
/**
* Flips the cards locally on the client
* @return
*/
public CardSet localFlip() {
CardSet newSet = new CardSet();
if(heldCards.isEmpty())
return newSet;
for (Card card: heldCards) {
if(card.permissionQuery(client.thisplayer, SEE)) {
if(locallyFlippedCards.contains(card)) {
//locallyFlippedCards.remove(card);
}
else {
locallyFlippedCards.add(card);
}
newSet.add(card);
}
}
return newSet;
}
public void resetLocalFlip() {
locallyFlippedCards = new CardSet();
}
/**
* Returns the {@link Table}
*/
public Table getTable() {
return table;
}
/**
* Moves the held cards by a <code>Point</code>
*/
public CardSet moveBy(Point point) {
return moveBy(point.x, point.y);
}
/**
* Moves the held cards by x, y
*/
public CardSet moveBy(int x, int y) {
CardSet newSet = new CardSet();
if(heldCards.isEmpty())
return newSet;
for (Card card: heldCards) {
if(card.permissionQuery(client.thisplayer, CONTROL)) {
card.moveBy(x, y);
newSet.add(card);
}
}
return newSet;
}
/**
* Syncs all of the clients to the server
*/
public void sync() {
String args = locationsString();
if (!args.isEmpty())
performPlayerAction(new PlayerAction(this, PlayerAction.SYNC_LOCATIONS, locationsString()));
}
public String locationsString() {
String args = "";
for(Card c: table.cards.ZValueOrder) {
args += c.getID() + PlayerAction.DEL + c.getLocation().x + PlayerAction.DEL + c.getLocation().y + PlayerAction.DEL + (c.isFaceUp() ? "1" : "0") + PlayerAction.DEL;
}
return args.isEmpty() ? "" : args.substring(0, args.length() - 1);
}
/**
* Called when a player performs an action
*/
public void playerActionPerformed(PlayerAction pa) {
PlayerAction action = null;
CardSet returnedCards = new CardSet();
switch(pa.getAction()) {
case PlayerAction.HOLD:
Vector<Card> toHold = table.getCardSetFromIDsOrdered(pa.getArgs());
heldCards.clear();
for(Card card : toHold) {
if(card.permissionQuery(client.thisplayer, CONTROL)) {
heldCards.add(card);
//set zordering
LinkedList<Card> zorder = table.cards.ZValueOrder;
zorder.remove(card);
zorder.add(card);
}
}
break;
case PlayerAction.FLIP:
returnedCards = flip();
if(returnedCards.isEmpty())
return;
action = new PlayerAction(this, PlayerAction.FLIP, returnedCards.toString());
performPlayerAction(action);
break;
case PlayerAction.LOCAL_FLIP:
returnedCards = localFlip();
if(returnedCards.isEmpty())
return;
action = new PlayerAction(this, PlayerAction.LOCAL_FLIP, returnedCards.toString());
performPlayerAction(action);
break;
case PlayerAction.MOVE:
String[] xy = pa.getArgs().split(PlayerAction.DEL + "");
returnedCards = moveBy(Integer.parseInt(xy[0]), Integer.parseInt(xy[1]));
if(returnedCards.isEmpty())
return;
action = new PlayerAction(this, PlayerAction.MOVE, xy[0] + PlayerAction.DEL + xy[1] + PlayerAction.DEL + returnedCards.toString());
performPlayerAction(action);
break;
case PlayerAction.SHUFFLE:
if(!(table.game.legalityCheck("shuffle"))){
break;
}
table.cards.shuffle();
performPlayerAction(new PlayerAction(this, PlayerAction.SYNC_LOCATIONS, locationsString()));
break;
case PlayerAction.SYNC_LOCATIONS:
String args = locationsString();
if (!args.isEmpty())
performPlayerAction(new PlayerAction(this, PlayerAction.SYNC_LOCATIONS, locationsString()));
break;
case PlayerAction.END_TURN:
Client source = (Client)(pa.getSource());
source.endTurn();
break;
case PlayerAction.NEW_GAME:
if(table.game != null){
if(!(table.game.legalityCheck("newgame"))){
break;
}
}
Client source2 = (Client)(pa.getSource());
if(pa.getArgs().charAt(0) == PlayerAction.SHOW_DIALOG){
table.getRoom().controller.getCardServer().newgame(source2,10);
table.getRoom().controller.getCardServer().gamename = pa.getArgs().substring(3);
performPlayerAction(new PlayerAction(this, PlayerAction.NEW_GAME, pa.getArgs()));
}
else if(pa.getArgs().charAt(0) == PlayerAction.NEW_GAME){
int response = Integer.parseInt(pa.getArgs().substring(1));
table.getRoom().controller.getCardServer().newgame(source2,response);
}
if(table.getRoom().controller.getCardServer().newGameAllRespondedQuery() && table.getRoom().controller.getCardServer().newGameApproved()){
table.newGame(table.getRoom().controller.getCardServer().gamename, ((Client)(pa.getSource())));
//System.out.println("at server?"); //IS ONLY ON SERVER...CALLED AT SERVER END REGARDLESS OF WHICH CLIENT!!!!!
addDecks = table.addDecksNumber;
System.out.println("pion"+addDecks+"iswin");
performPlayerAction(new PlayerAction(this, PlayerAction.NEW_GAME, addDecks+"::"+table.getRoom().controller.getCardServer().gamename));
CardSet toFlip = new CardSet();
for(Card c : table.cards) {
if(c.isFaceUp()) {
toFlip.add(c);
}
}
if(!toFlip.isEmpty()) {
performPlayerAction(new PlayerAction(this, PlayerAction.SET_FACE_UP, toFlip.toString()));
}
CardSet cards = table.cards;
performPlayerAction(new PlayerAction(this, PlayerAction.RESET_LOCAL_FLIP_TOALL, cards.toString()));
source2.endTurn();
}
if(!(table.getRoom().controller.getCardServer().newGameApproved())){
performPlayerAction(new PlayerAction(this, PlayerAction.NEW_GAME,PlayerAction.NEW_GAME+"no"));
}
break;
case PlayerAction.ADD_DECK:
table.addDeck(new Deck(pa.getArgs()));
performPlayerAction(new PlayerAction(this, PlayerAction.ADD_DECK, pa.getArgs()));
break;
case PlayerAction.SET_FACE_UP:
returnedCards = setFaceUp();
if(returnedCards.isEmpty())
return;
action = new PlayerAction(this, PlayerAction.SET_FACE_UP, returnedCards.toString());
performPlayerAction(action);
break;
case PlayerAction.SET_FACE_DOWN:
returnedCards = setFaceDown();
if(returnedCards.isEmpty())
return;
action = new PlayerAction(this, PlayerAction.SET_FACE_DOWN, returnedCards.toString());
performPlayerAction(action);
break;
case PlayerAction.RESET_LOCAL_FLIP:
locallyFlippedCards = new CardSet();
performPlayerAction(new PlayerAction(this, PlayerAction.RESET_LOCAL_FLIP, table.cards.toString()));
break;
case PlayerAction.CUSTOM:
table.game.playerActionPerformed(pa);
break;
case PlayerAction.DISCONNECT:
((Client)(pa.getSource())).disconnect();
System.out.println("Client Disconnected");
break;
}
}
/**
* Called to perform an action
*/
public void performPlayerAction(PlayerAction pa) {
switch(pa.getAction()) {
case(PlayerAction.FLIP):
client.sendCommandToAll(pa.getAction(), pa.getArgs());
break;
case(PlayerAction.LOCAL_FLIP):
client.sendCommand(pa.getAction(), pa.getArgs());
break;
case(PlayerAction.MOVE):
client.sendCommandToAllX(pa.getAction(), pa.getArgs());
break;
case(PlayerAction.NEW_GAME):
if(pa.getArgs().charAt(0) == PlayerAction.SHOW_DIALOG){
client.sendCommandToAllX(pa.getAction(), pa.getArgs());
}
else{
client.sendCommandToAll(pa.getAction(), pa.getArgs());
}
break;
case(PlayerAction.ADD_DECK):
client.sendCommandToAll(pa.getAction(), pa.getArgs());
break;
case PlayerAction.SYNC_LOCATIONS:
client.sendCommandToAll(pa.getAction(), pa.getArgs());
break;
case PlayerAction.SET_FACE_UP:
client.sendCommandToAll(pa.getAction(), pa.getArgs());
break;
case PlayerAction.SET_FACE_DOWN:
client.sendCommandToAll(pa.getAction(), pa.getArgs());
break;
case PlayerAction.RESET_LOCAL_FLIP:
// client.sendCommandToAll(pa.getAction(), pa.getArgs());
client.sendCommand(pa.getAction(), pa.getArgs());
break;
case PlayerAction.RESET_LOCAL_FLIP_TOALL:
System.out.println("Sending to all");
client.sendCommandToAll(PlayerAction.RESET_LOCAL_FLIP, pa.getArgs());
break;
case(PlayerAction.CUSTOM):
client.sendCommand(pa.getAction(), pa.getArgs());
break;
case(PlayerAction.SHOW_DIALOG):
client.sendCommand(pa.getAction(), pa.getArgs());
}
}
}
|