Package de.pokerth.test

Source Code of de.pokerth.test.TestBase$Guid

/*  PokerTH automated tests.
  Copyright (C) 2010 Lothar May

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as
  published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.

  You should have received a copy of the GNU Affero General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package de.pokerth.test;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.google.protobuf.ByteString;

import java.io.*;
import java.net.*;
import java.security.MessageDigest;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Collection;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import de.pokerth.protocol.ProtoBuf.AnnounceMessage;
import de.pokerth.protocol.ProtoBuf.AnnounceMessage.ServerType;
import de.pokerth.protocol.ProtoBuf.AuthClientResponseMessage;
import de.pokerth.protocol.ProtoBuf.ErrorMessage;
import de.pokerth.protocol.ProtoBuf.InitAckMessage;
import de.pokerth.protocol.ProtoBuf.InitMessage;
import de.pokerth.protocol.ProtoBuf.JoinExistingGameMessage;
import de.pokerth.protocol.ProtoBuf.JoinNewGameMessage;
import de.pokerth.protocol.ProtoBuf.NetGameInfo;
import de.pokerth.protocol.ProtoBuf.PokerTHMessage;
import de.pokerth.protocol.ProtoBuf.PokerTHMessage.PokerTHMessageType;
import de.pokerth.protocol.ProtoBuf.RejoinExistingGameMessage;

public abstract class TestBase {

  public final int PROTOCOL_VERSION_MAJOR = 5;
  public final int PROTOCOL_VERSION_MINOR = 1;
  public final String AuthUser = "user";
  public final String AuthPassword = "pencil";
  public final String GuestUser = "Guest112233";
  public final String GamePassword = "äöü?ßÄÖÜ";

  protected Socket sock;
  protected Connection dbConn;
  protected int lastRejoinGameId = 0;

  @Before
  public void dbInit() throws Exception {
    String configFileName = System.getProperty("user.home");
    if (System.getProperty("os.name").toLowerCase().indexOf("linux") > -1) {
      configFileName += "/.pokerth/config.xml";
    } else {
      configFileName += "/AppData/Roaming/pokerth/config.xml";
    }
    File file = new File(configFileName);
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document doc = db.parse(file);
    doc.getDocumentElement().normalize();
    Element configNode = (Element)doc.getElementsByTagName("Configuration").item(0);

    Element dbAddressNode = (Element)configNode.getElementsByTagName("DBServerAddress").item(0);
    String dbAddress = dbAddressNode.getAttribute("value");

    Element dbUserNode = (Element)configNode.getElementsByTagName("DBServerUser").item(0);
    String dbUser = dbUserNode.getAttribute("value");

    Element dbPasswordNode = (Element)configNode.getElementsByTagName("DBServerPassword").item(0);
    String dbPassword = dbPasswordNode.getAttribute("value");

    Element dbNameNode = (Element)configNode.getElementsByTagName("DBServerDatabaseName").item(0);
    String dbName = dbNameNode.getAttribute("value");

    final String dbUrl = "jdbc:mysql://" + dbAddress + ":3306/" + dbName;
    Class.forName("com.mysql.jdbc.Driver").newInstance ();
    dbConn = DriverManager.getConnection(dbUrl, dbUser, dbPassword);
  }

  @After
  public void dbClose() throws Exception {
    dbConn.close();
  }

  @Before
  public void setUp() throws Exception {
    Thread.sleep(2000);
    sock = new Socket("localhost", 7234);
  }

  @After
  public void tearDown() throws IOException {
    sock.close();
  }

  public void sendMessage(PokerTHMessage msg) throws Exception {
    sendMessage(msg, sock);
  }

  public void sendMessage(PokerTHMessage msg, Socket s) throws Exception {
    int size = msg.getSerializedSize();
    byte[] header = new byte[4];
    for (int i = 0; i < 4; i++)
    {
      header[i] = (new Integer(size >>> 24)).byteValue();
      size <<= 8;
    }
    s.getOutputStream().write(header);
    s.getOutputStream().write(msg.toByteArray());
  }

  public PokerTHMessage receiveMessage() throws Exception {
    return receiveMessage(sock);
  }

  public PokerTHMessage receiveMessage(Socket s) throws Exception {
    byte[] header = new byte[4];
    s.getInputStream().read(header);
    int size = 0;
    for (int i = 0; i < 4; i++) {
      size <<= 8;
      size |= (int)header[i];
    }
    byte[] data = new byte[size];
    s.getInputStream().read(data);
    return PokerTHMessage.parseFrom(data);
  }

  public int guestInit() throws Exception {
    return guestInit(sock);
  }

  public int guestInit(Socket s) throws Exception {
    int playerId = 0;
    PokerTHMessage msg = receiveMessage(s);
    assertTrue(msg.hasAnnounceMessage());

    AnnounceMessage.Version requestedVersion = AnnounceMessage.Version.newBuilder()
      .setMajorVersion(PROTOCOL_VERSION_MAJOR)
      .setMinorVersion(PROTOCOL_VERSION_MINOR)
      .build();
    InitMessage init = InitMessage.newBuilder()
      .setBuildId(0)
      .setLogin(InitMessage.LoginType.guestLogin)
      .setRequestedVersion(requestedVersion)
      .setNickName(GuestUser)
      .build();
    msg = PokerTHMessage.newBuilder()
      .setMessageType(PokerTHMessageType.Type_InitMessage)
      .setInitMessage(init)
      .build();
    sendMessage(msg, s);

    msg = receiveMessage(s);
    if (msg.hasInitAckMessage() && msg.getMessageType() == PokerTHMessageType.Type_InitAckMessage) {
      InitAckMessage initAck = msg.getInitAckMessage();
      assertTrue(initAck.getYourPlayerId() != 0L);
      assertTrue(!initAck.hasYourAvatarHash());
      playerId = initAck.getYourPlayerId();
    }
    else {
      failOnErrorMessage(msg);
      fail("Invalid message.");
    }
    return playerId;
  }

  public int userInit() throws Exception {
    return userInit(sock, AuthUser, AuthPassword);
  }

  public int userInit(Socket s, String user, String password) throws Exception {
    return userInit(s, user, password, null, null);
  }

  public class Guid {
    public byte[] value;
  }

  public int userInit(Socket s, String user, String password, byte[] avatarData, Guid lastSessionId) throws Exception {
    int playerId = 0;
    PokerTHMessage msg = receiveMessage(s);
    AnnounceMessage announce = msg.getAnnounceMessage();
    assertTrue(announce.getServerType() == ServerType.serverTypeInternetAuth);

    ScramSha1 scramAuth = new ScramSha1();

    // Send challenge.
    AnnounceMessage.Version requestedVersion = AnnounceMessage.Version.newBuilder()
        .setMajorVersion(PROTOCOL_VERSION_MAJOR)
        .setMinorVersion(PROTOCOL_VERSION_MINOR)
        .build();
    InitMessage.Builder initBuilder = InitMessage.newBuilder();
    initBuilder
        .setBuildId(0)
        .setLogin(InitMessage.LoginType.authenticatedLogin)
        .setRequestedVersion(requestedVersion)
        .setClientUserData(ByteString.copyFromUtf8(scramAuth.executeStep1(user)));
    if (avatarData != null) {
      initBuilder.setAvatarHash(ByteString.copyFrom(avatarData));
    }
    if (lastSessionId != null && lastSessionId.value != null) {
      initBuilder.setMyLastSessionId(ByteString.copyFrom(lastSessionId.value));
    }
    InitMessage init = initBuilder.build();
    msg = PokerTHMessage.newBuilder()
        .setMessageType(PokerTHMessageType.Type_InitMessage)
        .setInitMessage(init)
        .build();
    sendMessage(msg, s);

    msg = receiveMessage(s);

    if (msg.hasAuthServerChallengeMessage() && msg.getMessageType() == PokerTHMessageType.Type_AuthServerChallengeMessage)
    {
      String serverFirstMessage = new String(msg.getAuthServerChallengeMessage().getServerChallenge().toStringUtf8());
      AuthClientResponseMessage authClient = AuthClientResponseMessage.newBuilder()
        .setClientResponse(ByteString.copyFromUtf8(scramAuth.executeStep2(password, serverFirstMessage)))
        .build();

      msg = PokerTHMessage.newBuilder()
          .setMessageType(PokerTHMessageType.Type_AuthClientResponseMessage)
          .setAuthClientResponseMessage(authClient)
          .build();
      sendMessage(msg, s);
    }
    failOnErrorMessage(msg);

    msg = receiveMessage(s);
    failOnErrorMessage(msg);

    msg = receiveMessage(s);
    if (msg.hasInitAckMessage() && msg.getMessageType() == PokerTHMessageType.Type_InitAckMessage) {
      InitAckMessage initAck = msg.getInitAckMessage();
      assertTrue(initAck.getYourPlayerId() != 0L);
      assertTrue(!initAck.hasYourAvatarHash());
      playerId = initAck.getYourPlayerId();
      if (lastSessionId != null) {
        lastSessionId.value = initAck.getYourSessionId().toByteArray();
      }
      if (initAck.hasRejoinGameId()) {
        lastRejoinGameId = initAck.getRejoinGameId();
      }
      else {
        lastRejoinGameId = 0;
      }
    }
    else {
      failOnErrorMessage(msg);
      fail("Invalid message.");
    }
    return playerId;
  }

  public PokerTHMessage createGameRequestMsg(NetGameInfo gameInfo, String password, boolean autoLeave) {
    JoinNewGameMessage.Builder joinBuilder = JoinNewGameMessage.newBuilder();
    joinBuilder.setGameInfo(gameInfo);
    joinBuilder.setAutoLeave(autoLeave);
    if (!password.isEmpty()) {
      joinBuilder.setPassword(password);
    }
    JoinNewGameMessage joinNew = joinBuilder.build();

    PokerTHMessage msg = PokerTHMessage.newBuilder()
      .setMessageType(PokerTHMessageType.Type_JoinNewGameMessage)
      .setJoinNewGameMessage(joinNew)
      .build();
    return msg;
  }

  public PokerTHMessage joinGameRequestMsg(int gameId, String password, boolean autoLeave) {
    return joinGameRequestMsg(gameId, password, autoLeave, false);
  }

  public PokerTHMessage joinGameRequestMsg(int gameId, String password, boolean autoLeave, boolean spectateOnly) {
    JoinExistingGameMessage.Builder joinBuilder = JoinExistingGameMessage.newBuilder();
    joinBuilder.setGameId(gameId);
    joinBuilder.setAutoLeave(autoLeave);
    joinBuilder.setSpectateOnly(spectateOnly);
    if (!password.isEmpty()) {
      joinBuilder.setPassword(password);
    }
    JoinExistingGameMessage joinExisting = joinBuilder.build();

    PokerTHMessage msg = PokerTHMessage.newBuilder()
        .setMessageType(PokerTHMessageType.Type_JoinExistingGameMessage)
        .setJoinExistingGameMessage(joinExisting)
        .build();
    return msg;
  }

  public PokerTHMessage rejoinGameRequestMsg(int gameId, boolean autoLeave) {
    RejoinExistingGameMessage rejoinRequest = RejoinExistingGameMessage.newBuilder()
      .setGameId(gameId)
      .setAutoLeave(autoLeave)
      .build();

    PokerTHMessage msg = PokerTHMessage.newBuilder()
        .setMessageType(PokerTHMessageType.Type_RejoinExistingGameMessage)
        .setRejoinExistingGameMessage(rejoinRequest)
        .build();
    return msg;
  }

  public NetGameInfo createGameInfo(NetGameInfo.NetGameType gameType, int playerActionTimeout, int proposedGuiSpeed, int delayBetweenHands, NetGameInfo.EndRaiseMode endMode, int endRaiseValue, int sb,
      String gameName, Collection<Integer> manualBlinds, int maxNumPlayers, int raiseEveryMinutes, int raiseEveryHands, int startMoney) {

    NetGameInfo.Builder infoBuilder = NetGameInfo.newBuilder();
    infoBuilder
      .setNetGameType(gameType)
      .setPlayerActionTimeout(playerActionTimeout)
      .setProposedGuiSpeed(proposedGuiSpeed)
      .setDelayBetweenHands(delayBetweenHands)
      .setEndRaiseMode(endMode)
      .setEndRaiseSmallBlindValue(endRaiseValue)
      .setFirstSmallBlind(sb)
      .setGameName(gameName)
      .setMaxNumPlayers(maxNumPlayers)
      .addAllManualBlinds(manualBlinds)
      .setStartMoney(startMoney);

    if (raiseEveryMinutes > 0) {
      infoBuilder
        .setRaiseIntervalMode(NetGameInfo.RaiseIntervalMode.raiseOnMinutes)
        .setRaiseEveryMinutes(raiseEveryMinutes);
    }
    else {
      infoBuilder
        .setRaiseIntervalMode(NetGameInfo.RaiseIntervalMode.raiseOnHandNum)
        .setRaiseEveryHands(raiseEveryHands);
    }

    return infoBuilder.build();
  }

  void failOnErrorMessage(PokerTHMessage msg) {
    if (msg.hasErrorMessage())
    {
      ErrorMessage error = msg.getErrorMessage();
      fail("Received error: " + error.getErrorReason().toString());
    }
  }

  public byte[] decryptCards(final String password, final byte[] ciphertext) throws Exception
  {
    final MessageDigest shaDigest = MessageDigest.getInstance("SHA-1");
    byte[] pw1 = password.getBytes("UTF-8");

    byte[] keyHash1 = shaDigest.digest(pw1);
    keyHash1 = shaDigest.digest(keyHash1);
    byte[] pw2 = new byte[keyHash1.length + pw1.length];
    System.arraycopy(keyHash1, 0, pw2, 0, keyHash1.length);
    System.arraycopy(pw1, 0, pw2, keyHash1.length, pw1.length);
    byte[] keyHash2 = shaDigest.digest(pw2);
    keyHash2 = shaDigest.digest(keyHash2);

    byte[] key = new byte[16];
    System.arraycopy(keyHash1, 0, key, 0, key.length);
    byte[] iv = new byte[16];
    System.arraycopy(keyHash1, 16, iv, 0, 4);
    System.arraycopy(keyHash2, 0, iv, 4, 12);

    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");

    cipher.init(
      Cipher.DECRYPT_MODE,
      new SecretKeySpec(key, "AES"),
      new IvParameterSpec(iv));

    return cipher.doFinal(ciphertext);
  }
}
TOP

Related Classes of de.pokerth.test.TestBase$Guid

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.