<commit_before>/* bzflag
 * Copyright (c) 1993 - 2003 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */
// todo make this turn off for .net
#if defined(_WIN32)
	#pragma warning(disable: 4786)
#endif

#include <string.h>
#include <math.h>
#include <ctype.h>
#include <fstream>
#include "common.h"
#include "global.h"
#include "Ping.h"
#include "Protocol.h"
#include "TimeKeeper.h"
#include "bzfio.h"

// incessint rebuilding for current versioning
#include "version.h"

//
// PingPacket
//

const int		PingPacket::PacketSize = ServerIdPLen + 52;

PingPacket::PingPacket() : gameStyle(PlainGameStyle),
				maxPlayers(1),
				maxShots(1),
				rogueCount(0),
				redCount(0),
				greenCount(0),
				blueCount(0),
				purpleCount(0),
				rogueMax(1),
				redMax(1),
				greenMax(1),
				blueMax(1),
				purpleMax(1),
				shakeWins(0),
				shakeTimeout(0),
				maxPlayerScore(0),
				maxTeamScore(0),
				maxTime(0)
{
  // do nothing
}

PingPacket::~PingPacket()
{
  // do nothing
}

bool			PingPacket::read(int fd, struct sockaddr_in* addr)
{
  char buffer[PacketSize], serverVersion[9];
  uint16_t len, code;

  // get packet
  int n = recvMulticast(fd, buffer, sizeof(buffer), addr);
  if (n < 4)
    return false;

  // decode header
  void* buf = buffer;
  buf = nboUnpackUShort(buf, len);
  buf = nboUnpackUShort(buf, code);

  // make sure we got the rest of the message
  if (len != n - 4)
    return false;

  // check that it's a reply
  if (code != PingCodeReply)
    return false;

  // unpack body of reply
  buf = unpack(buf, serverVersion);

  // compare version against my version.  ignore last character of
  // version number.  that's only used to indicate compatible
  // client-side changes.
  return (strncmp(serverVersion, getServerVersion(), 7) == 0);
}

bool			PingPacket::waitForReply(int fd,
				const Address& from,
				int millisecondsToBlock)
{
  // block waiting on input.  if the incoming message is not from the
  // indicated source then ignore it and go back to waiting.  if the
  // incoming message is not a ping then ignore it and go back to waiting.
  float blockTime = 0.0001f * (float)millisecondsToBlock;
  TimeKeeper startTime = TimeKeeper::getCurrent();
  TimeKeeper currentTime = startTime;
  do {
    // prepare timeout
    const float timeLeft = blockTime - (currentTime - startTime);
    struct timeval timeout;
    timeout.tv_sec = long(floorf(timeLeft));
    timeout.tv_usec = long(1.0e+6f * (timeLeft - floorf(timeLeft)));

    // wait for input
    fd_set read_set;
    FD_ZERO(&read_set);
// turn off == signed/unsigned mismatch on win32
#if defined(_WIN32)
#pragma warning(disable: 4018)
#endif
    FD_SET(fd, &read_set);
#if defined(_WIN32)
#pragma warning(default: 4018)
#endif
    int nfound = select(fd+1, (fd_set*)&read_set, NULL, NULL, &timeout);

    // if got a message read it.  if a ping packet and from right
    // sender then return success.
    if (nfound < 0)
      return false;
    if (nfound > 0 && read(fd, NULL))
      if (sourceAddr == from)
	return true;

    currentTime = TimeKeeper::getCurrent();
  } while (currentTime - startTime < blockTime);
  return false;
}

bool			PingPacket::write(int fd,
					const struct sockaddr_in* addr) const
{
  char buffer[PacketSize];
  void* buf = buffer;
  buf = nboPackUShort(buf, PacketSize - 4);
  buf = nboPackUShort(buf, PingCodeReply);
  buf = pack(buf, getServerVersion());
  return sendMulticast(fd, buffer, sizeof(buffer), addr) == sizeof(buffer);
}

bool			PingPacket::isRequest(int fd,
				struct sockaddr_in* addr, int* minReplyTTL)
{
  if (fd < 0) return false;
  char buffer[6];
  void *msg = buffer;
  uint16_t len, code;
  int size = recvMulticast(fd, buffer, sizeof(buffer), addr);
  if (size < 2) return false;
  msg = nboUnpackUShort(msg, len);
  msg = nboUnpackUShort(msg, code);
  if (minReplyTTL && size == 6 && len == 2 && code == PingCodeRequest) {
    uint16_t ttl;
    msg = nboUnpackUShort(msg, ttl);
    *minReplyTTL = (int)ttl;
  }
  else if (minReplyTTL) {
    *minReplyTTL = 0;
  }
  return code == PingCodeRequest || code == PingCodeOldRequest;
}

bool			PingPacket::sendRequest(int fd,
					const struct sockaddr_in* addr,
					int replyMinTTL)
{
  if (fd < 0 || !addr) return false;
  char buffer[6];
  void *msg = buffer;
  msg = nboPackUShort(msg, 2);
  msg = nboPackUShort(msg, PingCodeRequest);
  msg = nboPackUShort(msg, (uint16_t)replyMinTTL);
  return sendMulticast(fd, buffer, sizeof(buffer), addr) == sizeof(buffer);
}

void*			PingPacket::unpack(void* buf, char* version)
{
  buf = nboUnpackString(buf, version, 8);
  buf = serverId.unpack(buf);
  buf = sourceAddr.unpack(buf);
  buf = nboUnpackUShort(buf, gameStyle);
  buf = nboUnpackUShort(buf, maxPlayers);
  buf = nboUnpackUShort(buf, maxShots);
  buf = nboUnpackUShort(buf, rogueCount);
  buf = nboUnpackUShort(buf, redCount);
  buf = nboUnpackUShort(buf, greenCount);
  buf = nboUnpackUShort(buf, blueCount);
  buf = nboUnpackUShort(buf, purpleCount);
  buf = nboUnpackUShort(buf, rogueMax);
  buf = nboUnpackUShort(buf, redMax);
  buf = nboUnpackUShort(buf, greenMax);
  buf = nboUnpackUShort(buf, blueMax);
  buf = nboUnpackUShort(buf, purpleMax);
  buf = nboUnpackUShort(buf, shakeWins);
  buf = nboUnpackUShort(buf, shakeTimeout);
  buf = nboUnpackUShort(buf, maxPlayerScore);
  buf = nboUnpackUShort(buf, maxTeamScore);
  buf = nboUnpackUShort(buf, maxTime);
  return buf;
}

void*			PingPacket::pack(void* buf, const char* version) const
{
  buf = nboPackString(buf, version, 8);
  buf = serverId.pack(buf);
  buf = sourceAddr.pack(buf);
  buf = nboPackUShort(buf, gameStyle);
  buf = nboPackUShort(buf, maxPlayers);
  buf = nboPackUShort(buf, maxShots);
  buf = nboPackUShort(buf, rogueCount);
  buf = nboPackUShort(buf, redCount);
  buf = nboPackUShort(buf, greenCount);
  buf = nboPackUShort(buf, blueCount);
  buf = nboPackUShort(buf, purpleCount);
  buf = nboPackUShort(buf, rogueMax);
  buf = nboPackUShort(buf, redMax);
  buf = nboPackUShort(buf, greenMax);
  buf = nboPackUShort(buf, blueMax);
  buf = nboPackUShort(buf, purpleMax);
  buf = nboPackUShort(buf, shakeWins);
  buf = nboPackUShort(buf, shakeTimeout);	// 1/10ths of second
  buf = nboPackUShort(buf, maxPlayerScore);
  buf = nboPackUShort(buf, maxTeamScore);
  buf = nboPackUShort(buf, maxTime);
  return buf;
}

void			PingPacket::packHex(char* buf) const
{
  buf = packHex16(buf, gameStyle);
  buf = packHex16(buf, maxPlayers);
  buf = packHex16(buf, maxShots);
  buf = packHex16(buf, rogueCount);
  buf = packHex16(buf, redCount);
  buf = packHex16(buf, greenCount);
  buf = packHex16(buf, blueCount);
  buf = packHex16(buf, purpleCount);
  buf = packHex16(buf, rogueMax);
  buf = packHex16(buf, redMax);
  buf = packHex16(buf, greenMax);
  buf = packHex16(buf, blueMax);
  buf = packHex16(buf, purpleMax);
  buf = packHex16(buf, shakeWins);
  buf = packHex16(buf, shakeTimeout);
  buf = packHex16(buf, maxPlayerScore);
  buf = packHex16(buf, maxTeamScore);
  buf = packHex16(buf, maxTime);
}

void			PingPacket::unpackHex(char* buf)
{
  buf = unpackHex16(buf, gameStyle);
  buf = unpackHex16(buf, maxPlayers);
  buf = unpackHex16(buf, maxShots);
  buf = unpackHex16(buf, rogueCount);
  buf = unpackHex16(buf, redCount);
  buf = unpackHex16(buf, greenCount);
  buf = unpackHex16(buf, blueCount);
  buf = unpackHex16(buf, purpleCount);
  buf = unpackHex16(buf, rogueMax);
  buf = unpackHex16(buf, redMax);
  buf = unpackHex16(buf, greenMax);
  buf = unpackHex16(buf, blueMax);
  buf = unpackHex16(buf, purpleMax);
  buf = unpackHex16(buf, shakeWins);
  buf = unpackHex16(buf, shakeTimeout);
  buf = unpackHex16(buf, maxPlayerScore);
  buf = unpackHex16(buf, maxTeamScore);
  buf = unpackHex16(buf, maxTime);
}

void			PingPacket::repackHexPlayerCounts(
				char* buf, int* counts)
{
  buf += 2 * 2 * 3;
  buf = packHex16(buf, (uint16_t)counts[0]);
  buf = packHex16(buf, (uint16_t)counts[1]);
  buf = packHex16(buf, (uint16_t)counts[2]);
  buf = packHex16(buf, (uint16_t)counts[3]);
  buf = packHex16(buf, (uint16_t)counts[4]);
}

int			PingPacket::hex2bin(char d)
{
  switch (d) {
    case '0': return 0;
    case '1': return 1;
    case '2': return 2;
    case '3': return 3;
    case '4': return 4;
    case '5': return 5;
    case '6': return 6;
    case '7': return 7;
    case '8': return 8;
    case '9': return 9;
    case 'A':
    case 'a': return 10;
    case 'B':
    case 'b': return 11;
    case 'C':
    case 'c': return 12;
    case 'D':
    case 'd': return 13;
    case 'E':
    case 'e': return 14;
    case 'F':
    case 'f': return 15;
  }
  return 0;
}

char			PingPacket::bin2hex(int d)
{
  static const char* digit = "0123456789abcdef";
  return digit[d];
}

char*			PingPacket::packHex16(char* buf, uint16_t v)
{
  *buf++ = bin2hex((v >> 12) & 0xf);
  *buf++ = bin2hex((v >>  8) & 0xf);
  *buf++ = bin2hex((v >>  4) & 0xf);
  *buf++ = bin2hex( v        & 0xf);
  return buf;
}

char*			PingPacket::unpackHex16(char* buf, uint16_t& v)
{
  uint16_t d = 0;
  d = (d << 4) | hex2bin(*buf++);
  d = (d << 4) | hex2bin(*buf++);
  d = (d << 4) | hex2bin(*buf++);
  d = (d << 4) | hex2bin(*buf++);
  v = d;
  return buf;
}
// ex: shiftwidth=2 tabstop=8

void			 PingPacket::zeroPlayerCounts()
{
  blueCount = 0; greenCount = 0; redCount = 0; purpleCount = 0; rogueCount = 0;
}

// serialize packet to file -- note lack of error checking
// must write to a binary file if we use plain "pack"
void			 PingPacket::writeToFile (ostream& out) const
{
  if (!out) return;

  char buffer[PingPacket::PacketSize];
  void* buf = buffer;
  buf = nboPackUShort(buf, PingPacket::PacketSize - 4);
  buf = nboPackUShort(buf, PingCodeReply);
  buf = pack(buf, getServerVersion());
  out.write(buffer,sizeof(buffer));
}

// de serialize packet from file
// must read from a binary file if we use plain "unpack"
bool			 PingPacket::readFromFile(istream& in)
{
  if (!in) return false;

  char buffer[PingPacket::PacketSize], serverVersion[9];
  uint16_t len, code;

  // get packet
  in.read(buffer, sizeof(buffer));
  if ((size_t)in.gcount() < sizeof(buffer)){
    return false;
  }

  // decode header
  void* buf = buffer;
  buf = nboUnpackUShort(buf, len);
  buf = nboUnpackUShort(buf, code);

  // make sure we got the rest of the message
  if (len != in.gcount() - 4){
    return false;
  }

  // unpack body of reply
  buf = unpack(buf, serverVersion);

  // compare version against my version.  ignore last character of
  // version number.  that's only used to indicate compatible
  // client-side changes.
  return (strncmp(serverVersion, getServerVersion(), 7) == 0);
}
<commit_msg>PingCodeOldRequest is gone, don't use it<commit_after>/* bzflag
 * Copyright (c) 1993 - 2003 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */
// todo make this turn off for .net
#if defined(_WIN32)
	#pragma warning(disable: 4786)
#endif

#include <string.h>
#include <math.h>
#include <ctype.h>
#include <fstream>
#include "common.h"
#include "global.h"
#include "Ping.h"
#include "Protocol.h"
#include "TimeKeeper.h"
#include "bzfio.h"

// incessint rebuilding for current versioning
#include "version.h"

//
// PingPacket
//

const int		PingPacket::PacketSize = ServerIdPLen + 52;

PingPacket::PingPacket() : gameStyle(PlainGameStyle),
				maxPlayers(1),
				maxShots(1),
				rogueCount(0),
				redCount(0),
				greenCount(0),
				blueCount(0),
				purpleCount(0),
				rogueMax(1),
				redMax(1),
				greenMax(1),
				blueMax(1),
				purpleMax(1),
				shakeWins(0),
				shakeTimeout(0),
				maxPlayerScore(0),
				maxTeamScore(0),
				maxTime(0)
{
  // do nothing
}

PingPacket::~PingPacket()
{
  // do nothing
}

bool			PingPacket::read(int fd, struct sockaddr_in* addr)
{
  char buffer[PacketSize], serverVersion[9];
  uint16_t len, code;

  // get packet
  int n = recvMulticast(fd, buffer, sizeof(buffer), addr);
  if (n < 4)
    return false;

  // decode header
  void* buf = buffer;
  buf = nboUnpackUShort(buf, len);
  buf = nboUnpackUShort(buf, code);

  // make sure we got the rest of the message
  if (len != n - 4)
    return false;

  // check that it's a reply
  if (code != PingCodeReply)
    return false;

  // unpack body of reply
  buf = unpack(buf, serverVersion);

  // compare version against my version.  ignore last character of
  // version number.  that's only used to indicate compatible
  // client-side changes.
  return (strncmp(serverVersion, getServerVersion(), 7) == 0);
}

bool			PingPacket::waitForReply(int fd,
				const Address& from,
				int millisecondsToBlock)
{
  // block waiting on input.  if the incoming message is not from the
  // indicated source then ignore it and go back to waiting.  if the
  // incoming message is not a ping then ignore it and go back to waiting.
  float blockTime = 0.0001f * (float)millisecondsToBlock;
  TimeKeeper startTime = TimeKeeper::getCurrent();
  TimeKeeper currentTime = startTime;
  do {
    // prepare timeout
    const float timeLeft = blockTime - (currentTime - startTime);
    struct timeval timeout;
    timeout.tv_sec = long(floorf(timeLeft));
    timeout.tv_usec = long(1.0e+6f * (timeLeft - floorf(timeLeft)));

    // wait for input
    fd_set read_set;
    FD_ZERO(&read_set);
// turn off == signed/unsigned mismatch on win32
#if defined(_WIN32)
#pragma warning(disable: 4018)
#endif
    FD_SET(fd, &read_set);
#if defined(_WIN32)
#pragma warning(default: 4018)
#endif
    int nfound = select(fd+1, (fd_set*)&read_set, NULL, NULL, &timeout);

    // if got a message read it.  if a ping packet and from right
    // sender then return success.
    if (nfound < 0)
      return false;
    if (nfound > 0 && read(fd, NULL))
      if (sourceAddr == from)
	return true;

    currentTime = TimeKeeper::getCurrent();
  } while (currentTime - startTime < blockTime);
  return false;
}

bool			PingPacket::write(int fd,
					const struct sockaddr_in* addr) const
{
  char buffer[PacketSize];
  void* buf = buffer;
  buf = nboPackUShort(buf, PacketSize - 4);
  buf = nboPackUShort(buf, PingCodeReply);
  buf = pack(buf, getServerVersion());
  return sendMulticast(fd, buffer, sizeof(buffer), addr) == sizeof(buffer);
}

bool			PingPacket::isRequest(int fd,
				struct sockaddr_in* addr, int* minReplyTTL)
{
  if (fd < 0) return false;
  char buffer[6];
  void *msg = buffer;
  uint16_t len, code;
  int size = recvMulticast(fd, buffer, sizeof(buffer), addr);
  if (size < 2) return false;
  msg = nboUnpackUShort(msg, len);
  msg = nboUnpackUShort(msg, code);
  if (minReplyTTL && size == 6 && len == 2 && code == PingCodeRequest) {
    uint16_t ttl;
    msg = nboUnpackUShort(msg, ttl);
    *minReplyTTL = (int)ttl;
  }
  else if (minReplyTTL) {
    *minReplyTTL = 0;
  }
  return code == PingCodeRequest;
}

bool			PingPacket::sendRequest(int fd,
					const struct sockaddr_in* addr,
					int replyMinTTL)
{
  if (fd < 0 || !addr) return false;
  char buffer[6];
  void *msg = buffer;
  msg = nboPackUShort(msg, 2);
  msg = nboPackUShort(msg, PingCodeRequest);
  msg = nboPackUShort(msg, (uint16_t)replyMinTTL);
  return sendMulticast(fd, buffer, sizeof(buffer), addr) == sizeof(buffer);
}

void*			PingPacket::unpack(void* buf, char* version)
{
  buf = nboUnpackString(buf, version, 8);
  buf = serverId.unpack(buf);
  buf = sourceAddr.unpack(buf);
  buf = nboUnpackUShort(buf, gameStyle);
  buf = nboUnpackUShort(buf, maxPlayers);
  buf = nboUnpackUShort(buf, maxShots);
  buf = nboUnpackUShort(buf, rogueCount);
  buf = nboUnpackUShort(buf, redCount);
  buf = nboUnpackUShort(buf, greenCount);
  buf = nboUnpackUShort(buf, blueCount);
  buf = nboUnpackUShort(buf, purpleCount);
  buf = nboUnpackUShort(buf, rogueMax);
  buf = nboUnpackUShort(buf, redMax);
  buf = nboUnpackUShort(buf, greenMax);
  buf = nboUnpackUShort(buf, blueMax);
  buf = nboUnpackUShort(buf, purpleMax);
  buf = nboUnpackUShort(buf, shakeWins);
  buf = nboUnpackUShort(buf, shakeTimeout);
  buf = nboUnpackUShort(buf, maxPlayerScore);
  buf = nboUnpackUShort(buf, maxTeamScore);
  buf = nboUnpackUShort(buf, maxTime);
  return buf;
}

void*			PingPacket::pack(void* buf, const char* version) const
{
  buf = nboPackString(buf, version, 8);
  buf = serverId.pack(buf);
  buf = sourceAddr.pack(buf);
  buf = nboPackUShort(buf, gameStyle);
  buf = nboPackUShort(buf, maxPlayers);
  buf = nboPackUShort(buf, maxShots);
  buf = nboPackUShort(buf, rogueCount);
  buf = nboPackUShort(buf, redCount);
  buf = nboPackUShort(buf, greenCount);
  buf = nboPackUShort(buf, blueCount);
  buf = nboPackUShort(buf, purpleCount);
  buf = nboPackUShort(buf, rogueMax);
  buf = nboPackUShort(buf, redMax);
  buf = nboPackUShort(buf, greenMax);
  buf = nboPackUShort(buf, blueMax);
  buf = nboPackUShort(buf, purpleMax);
  buf = nboPackUShort(buf, shakeWins);
  buf = nboPackUShort(buf, shakeTimeout);	// 1/10ths of second
  buf = nboPackUShort(buf, maxPlayerScore);
  buf = nboPackUShort(buf, maxTeamScore);
  buf = nboPackUShort(buf, maxTime);
  return buf;
}

void			PingPacket::packHex(char* buf) const
{
  buf = packHex16(buf, gameStyle);
  buf = packHex16(buf, maxPlayers);
  buf = packHex16(buf, maxShots);
  buf = packHex16(buf, rogueCount);
  buf = packHex16(buf, redCount);
  buf = packHex16(buf, greenCount);
  buf = packHex16(buf, blueCount);
  buf = packHex16(buf, purpleCount);
  buf = packHex16(buf, rogueMax);
  buf = packHex16(buf, redMax);
  buf = packHex16(buf, greenMax);
  buf = packHex16(buf, blueMax);
  buf = packHex16(buf, purpleMax);
  buf = packHex16(buf, shakeWins);
  buf = packHex16(buf, shakeTimeout);
  buf = packHex16(buf, maxPlayerScore);
  buf = packHex16(buf, maxTeamScore);
  buf = packHex16(buf, maxTime);
}

void			PingPacket::unpackHex(char* buf)
{
  buf = unpackHex16(buf, gameStyle);
  buf = unpackHex16(buf, maxPlayers);
  buf = unpackHex16(buf, maxShots);
  buf = unpackHex16(buf, rogueCount);
  buf = unpackHex16(buf, redCount);
  buf = unpackHex16(buf, greenCount);
  buf = unpackHex16(buf, blueCount);
  buf = unpackHex16(buf, purpleCount);
  buf = unpackHex16(buf, rogueMax);
  buf = unpackHex16(buf, redMax);
  buf = unpackHex16(buf, greenMax);
  buf = unpackHex16(buf, blueMax);
  buf = unpackHex16(buf, purpleMax);
  buf = unpackHex16(buf, shakeWins);
  buf = unpackHex16(buf, shakeTimeout);
  buf = unpackHex16(buf, maxPlayerScore);
  buf = unpackHex16(buf, maxTeamScore);
  buf = unpackHex16(buf, maxTime);
}

void			PingPacket::repackHexPlayerCounts(
				char* buf, int* counts)
{
  buf += 2 * 2 * 3;
  buf = packHex16(buf, (uint16_t)counts[0]);
  buf = packHex16(buf, (uint16_t)counts[1]);
  buf = packHex16(buf, (uint16_t)counts[2]);
  buf = packHex16(buf, (uint16_t)counts[3]);
  buf = packHex16(buf, (uint16_t)counts[4]);
}

int			PingPacket::hex2bin(char d)
{
  switch (d) {
    case '0': return 0;
    case '1': return 1;
    case '2': return 2;
    case '3': return 3;
    case '4': return 4;
    case '5': return 5;
    case '6': return 6;
    case '7': return 7;
    case '8': return 8;
    case '9': return 9;
    case 'A':
    case 'a': return 10;
    case 'B':
    case 'b': return 11;
    case 'C':
    case 'c': return 12;
    case 'D':
    case 'd': return 13;
    case 'E':
    case 'e': return 14;
    case 'F':
    case 'f': return 15;
  }
  return 0;
}

char			PingPacket::bin2hex(int d)
{
  static const char* digit = "0123456789abcdef";
  return digit[d];
}

char*			PingPacket::packHex16(char* buf, uint16_t v)
{
  *buf++ = bin2hex((v >> 12) & 0xf);
  *buf++ = bin2hex((v >>  8) & 0xf);
  *buf++ = bin2hex((v >>  4) & 0xf);
  *buf++ = bin2hex( v        & 0xf);
  return buf;
}

char*			PingPacket::unpackHex16(char* buf, uint16_t& v)
{
  uint16_t d = 0;
  d = (d << 4) | hex2bin(*buf++);
  d = (d << 4) | hex2bin(*buf++);
  d = (d << 4) | hex2bin(*buf++);
  d = (d << 4) | hex2bin(*buf++);
  v = d;
  return buf;
}
// ex: shiftwidth=2 tabstop=8

void			 PingPacket::zeroPlayerCounts()
{
  blueCount = 0; greenCount = 0; redCount = 0; purpleCount = 0; rogueCount = 0;
}

// serialize packet to file -- note lack of error checking
// must write to a binary file if we use plain "pack"
void			 PingPacket::writeToFile (ostream& out) const
{
  if (!out) return;

  char buffer[PingPacket::PacketSize];
  void* buf = buffer;
  buf = nboPackUShort(buf, PingPacket::PacketSize - 4);
  buf = nboPackUShort(buf, PingCodeReply);
  buf = pack(buf, getServerVersion());
  out.write(buffer,sizeof(buffer));
}

// de serialize packet from file
// must read from a binary file if we use plain "unpack"
bool			 PingPacket::readFromFile(istream& in)
{
  if (!in) return false;

  char buffer[PingPacket::PacketSize], serverVersion[9];
  uint16_t len, code;

  // get packet
  in.read(buffer, sizeof(buffer));
  if ((size_t)in.gcount() < sizeof(buffer)){
    return false;
  }

  // decode header
  void* buf = buffer;
  buf = nboUnpackUShort(buf, len);
  buf = nboUnpackUShort(buf, code);

  // make sure we got the rest of the message
  if (len != in.gcount() - 4){
    return false;
  }

  // unpack body of reply
  buf = unpack(buf, serverVersion);

  // compare version against my version.  ignore last character of
  // version number.  that's only used to indicate compatible
  // client-side changes.
  return (strncmp(serverVersion, getServerVersion(), 7) == 0);
}
<|endoftext|>


<commit_before>/*
** Copyright 2018 Centreon
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
**
** For more information : contact@centreon.com
*/

#include <QFile>
#include <QTextStream>
#include <QStringList>
#include <memory>
#include <gtest/gtest.h>
#include "com/centreon/broker/config/applier/init.hh"
#include "com/centreon/broker/exceptions/msg.hh"
#include "com/centreon/broker/instance_broadcast.hh"
#include "com/centreon/broker/simu/luabinding.hh"
#include "com/centreon/broker/misc/shared_ptr.hh"
#include "com/centreon/broker/modules/loader.hh"
#include "com/centreon/broker/neb/events.hh"
#include "com/centreon/broker/storage/status.hh"

using namespace com::centreon::broker;
using namespace com::centreon::broker::misc;
using namespace com::centreon::broker::simu;

class SimuGenericTest : public ::testing::Test {
 public:
  void SetUp() {
    try {
      config::applier::init();
    }
    catch (std::exception const& e) {
      (void) e;
    }
  }
  void TearDown() {
    config::applier::deinit();
  }

  void CreateScript(std::string const& filename, QString const& content) {
    QFile file(filename.c_str());
    file.open(QIODevice::WriteOnly);
    QTextStream out(&file);
    out << content;
  }

  QStringList ReadFile(QString const& filename) {
    QStringList retval;
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly))
      return retval;

    QTextStream in(&file);

    while (!in.atEnd()) {
      retval << in.readLine();
    }

    file.close();
    return retval;
  }

  void RemoveFile(std::string const& filename) {
    QFile file(filename.c_str());
    file.remove();
  }
};

// When a lua script that does not exist is loaded
// Then an exception is thrown
TEST_F(SimuGenericTest, MissingScript) {
  QMap<QString, QVariant> conf;
  ASSERT_THROW(
    new luabinding(
      "/tmp/this_script_does_not_exist.lua",conf),
		exceptions::msg);
}

// When a lua script with error such as number divided by nil is loaded
// Then an exception is thrown
TEST_F(SimuGenericTest, FaultyScript) {
  QMap<QString, QVariant> conf;
  std::string filename("/tmp/faulty.lua");
  CreateScript(filename, "local a = { 1, 2, 3 }\n"
                         "local b = 18 / a[4]");
  ASSERT_THROW(
    new luabinding(filename, conf),
    exceptions::msg);
  RemoveFile(filename);
}

// When a lua script that does not contain an init() function is loaded
// Then an exception is thrown
TEST_F(SimuGenericTest, WithoutInit) {
  QMap<QString, QVariant> conf;
  std::string filename("/tmp/without_init.lua");
  CreateScript(filename, "local a = { 1, 2, 3 }\n");
  ASSERT_THROW(
    new luabinding(filename, conf), exceptions::msg);
  RemoveFile(filename);
}

// When a json parameters file exists but the lua script is incomplete
// Then an exception is thrown
TEST_F(SimuGenericTest, IncompleteScript) {
  std::string filename("/tmp/bad_init.lua");
  CreateScript(filename, "function init()\n"
                         "end\n"
                         "local a = { 1, 2, 3 }\n");
  QMap<QString, QVariant> conf;
  ASSERT_THROW(new luabinding(
                     filename,
                     conf),
                  exceptions::msg);
  RemoveFile(filename);
}

// When a script read() function does not return nil or a Lua table
// Then an exception is thrown
TEST_F(SimuGenericTest, ReadReturnValue1) {
  std::string filename("/tmp/bad_read.lua");
  CreateScript(filename, "function init()\n"
                         "end\n"
                         "function read()\n"
                         "return 2\n"
                         "end\n");
  QMap<QString, QVariant> conf;
  std::auto_ptr<luabinding> lb(new luabinding(
                     filename,
                     conf));
  misc::shared_ptr<io::data> d;
  ASSERT_THROW(lb->read(d), exceptions::msg);
  RemoveFile(filename);
}

// When a script read() function returns nil
// Then no exception is thrown
TEST_F(SimuGenericTest, ReadReturnValue2) {
  std::string filename("/tmp/good_read.lua");
  CreateScript(filename, "function init()\n"
                         "end\n"
                         "function read()\n"
                         "return nil\n"
                         "end\n");
  QMap<QString, QVariant> conf;
  std::auto_ptr<luabinding> lb(new luabinding(
                     filename,
                     conf));
  misc::shared_ptr<io::data> d;
  ASSERT_FALSE(lb->read(d));
  RemoveFile(filename);
}

// When a script read() function returns a table
// And the table does not represent an event
// Then no exception is thrown
// And read() returns false
TEST_F(SimuGenericTest, ReadReturnValue3) {
  std::string filename("/tmp/good_read.lua");
  CreateScript(filename, "function init()\n"
                         "end\n"
                         "function read()\n"
                         "return { a='toto' }\n"
                         "end\n");
  QMap<QString, QVariant> conf;
  std::auto_ptr<luabinding> lb(new luabinding(
                     filename,
                     conf));
  misc::shared_ptr<io::data> d;
  ASSERT_FALSE(lb->read(d));
  RemoveFile(filename);
}

// When a script read() function returns a table
// And the table is an event
// Then no exception is thrown
// And read() returns true
TEST_F(SimuGenericTest, ReadReturnValue4) {
  std::string filename("/tmp/good_read.lua");
  CreateScript(filename, "function init()\n"
                         "end\n"
                         "function read()\n"
                         "return { _type=65559,\n"
                                  "service_id=1,\n"
                                  "ctime=1536659255,\n"
                                  "host_id=2,\n"
                                  "element=23,\n"
                                  "category=1,\n"
                                  "description=\"Super description\"\n"
                         "}\n"
                         "end\n");
  QMap<QString, QVariant> conf;
  modules::loader l;
  l.load_file("./neb/10-neb.so");
  std::auto_ptr<luabinding> lb(new luabinding(
                     filename,
                     conf));
  misc::shared_ptr<io::data> d;
  ASSERT_TRUE(lb->read(d));
  RemoveFile(filename);
  neb::service* svc(static_cast<neb::service*>(d.data()));
  ASSERT_TRUE(svc->type() == 65559);
  ASSERT_EQ(svc->host_id, 2);
  std::cout << "service description: " << svc->service_description.toStdString();
  ASSERT_TRUE(svc->service_description == "Super description");
}

// When a script read() function returns a table
// And the table is an event
// Then no exception is thrown
// And read() returns true
TEST_F(SimuGenericTest, ReadReturnCustomVariable) {
  std::string filename("/tmp/good_read.lua");
  CreateScript(filename, "function init()\n"
                         "end\n"
                         "function read()\n"
                         "  return {\n"
                         "    service_id=498,\n"
                         "    _type=65539,\n"
                         "    update_time=1538146454,\n"
                         "    modified=false,\n"
                         "    host_id=31,\n"
                         "    element=3,\n"
                         "    name=\"PROCESSNAME\",\n"
                         "    category=1,\n"
                         "    value=\"centengine\",\n"
                         "    default_value=\"centengine\"}\n"
                         "end\n");
  QMap<QString, QVariant> conf;
  modules::loader l;
  l.load_file("./neb/10-neb.so");
  std::auto_ptr<luabinding> lb(new luabinding(
                     filename,
                     conf));
  misc::shared_ptr<io::data> d;
  ASSERT_TRUE(lb->read(d));
  RemoveFile(filename);
  neb::custom_variable* cv(static_cast<neb::custom_variable*>(d.data()));
  ASSERT_TRUE(cv->type() == 65539);
  ASSERT_EQ(cv->host_id, 31);
  ASSERT_TRUE(cv->enabled);
}
<commit_msg>enh(simu): Migration to c++11<commit_after>/*
** Copyright 2018 Centreon
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
**
** For more information : contact@centreon.com
*/

#include <QFile>
#include <QTextStream>
#include <QStringList>
#include <memory>
#include <gtest/gtest.h>
#include "com/centreon/broker/config/applier/init.hh"
#include "com/centreon/broker/exceptions/msg.hh"
#include "com/centreon/broker/instance_broadcast.hh"
#include "com/centreon/broker/simu/luabinding.hh"
#include "com/centreon/broker/modules/loader.hh"
#include "com/centreon/broker/neb/events.hh"
#include "com/centreon/broker/storage/status.hh"

using namespace com::centreon::broker;
using namespace com::centreon::broker::misc;
using namespace com::centreon::broker::simu;

class SimuGenericTest : public ::testing::Test {
 public:
  void SetUp() {
    try {
      config::applier::init();
    }
    catch (std::exception const& e) {
      (void) e;
    }
  }
  void TearDown() {
    config::applier::deinit();
  }

  void CreateScript(std::string const& filename, QString const& content) {
    QFile file(filename.c_str());
    file.open(QIODevice::WriteOnly);
    QTextStream out(&file);
    out << content;
  }

  QStringList ReadFile(QString const& filename) {
    QStringList retval;
    QFile file(filename);
    if (!file.open(QIODevice::ReadOnly))
      return retval;

    QTextStream in(&file);

    while (!in.atEnd()) {
      retval << in.readLine();
    }

    file.close();
    return retval;
  }

  void RemoveFile(std::string const& filename) {
    QFile file(filename.c_str());
    file.remove();
  }
};

// When a lua script that does not exist is loaded
// Then an exception is thrown
TEST_F(SimuGenericTest, MissingScript) {
  QMap<QString, QVariant> conf;
  ASSERT_THROW(
    new luabinding(
      "/tmp/this_script_does_not_exist.lua",conf),
		exceptions::msg);
}

// When a lua script with error such as number divided by nil is loaded
// Then an exception is thrown
TEST_F(SimuGenericTest, FaultyScript) {
  QMap<QString, QVariant> conf;
  std::string filename("/tmp/faulty.lua");
  CreateScript(filename, "local a = { 1, 2, 3 }\n"
                         "local b = 18 / a[4]");
  ASSERT_THROW(
    new luabinding(filename, conf),
    exceptions::msg);
  RemoveFile(filename);
}

// When a lua script that does not contain an init() function is loaded
// Then an exception is thrown
TEST_F(SimuGenericTest, WithoutInit) {
  QMap<QString, QVariant> conf;
  std::string filename("/tmp/without_init.lua");
  CreateScript(filename, "local a = { 1, 2, 3 }\n");
  ASSERT_THROW(
    new luabinding(filename, conf), exceptions::msg);
  RemoveFile(filename);
}

// When a json parameters file exists but the lua script is incomplete
// Then an exception is thrown
TEST_F(SimuGenericTest, IncompleteScript) {
  std::string filename("/tmp/bad_init.lua");
  CreateScript(filename, "function init()\n"
                         "end\n"
                         "local a = { 1, 2, 3 }\n");
  QMap<QString, QVariant> conf;
  ASSERT_THROW(new luabinding(
                     filename,
                     conf),
                  exceptions::msg);
  RemoveFile(filename);
}

// When a script read() function does not return nil or a Lua table
// Then an exception is thrown
TEST_F(SimuGenericTest, ReadReturnValue1) {
  std::string filename("/tmp/bad_read.lua");
  CreateScript(filename, "function init()\n"
                         "end\n"
                         "function read()\n"
                         "return 2\n"
                         "end\n");
  QMap<QString, QVariant> conf;
  std::unique_ptr<luabinding> lb(new luabinding(
                     filename,
                     conf));
  std::shared_ptr<io::data> d;
  ASSERT_THROW(lb->read(d), exceptions::msg);
  RemoveFile(filename);
}

// When a script read() function returns nil
// Then no exception is thrown
TEST_F(SimuGenericTest, ReadReturnValue2) {
  std::string filename("/tmp/good_read.lua");
  CreateScript(filename, "function init()\n"
                         "end\n"
                         "function read()\n"
                         "return nil\n"
                         "end\n");
  QMap<QString, QVariant> conf;
  std::unique_ptr<luabinding> lb(new luabinding(
                     filename,
                     conf));
  std::shared_ptr<io::data> d;
  ASSERT_FALSE(lb->read(d));
  RemoveFile(filename);
}

// When a script read() function returns a table
// And the table does not represent an event
// Then no exception is thrown
// And read() returns false
TEST_F(SimuGenericTest, ReadReturnValue3) {
  std::string filename("/tmp/good_read.lua");
  CreateScript(filename, "function init()\n"
                         "end\n"
                         "function read()\n"
                         "return { a='toto' }\n"
                         "end\n");
  QMap<QString, QVariant> conf;
  std::unique_ptr<luabinding> lb(new luabinding(
                     filename,
                     conf));
  std::shared_ptr<io::data> d;
  ASSERT_FALSE(lb->read(d));
  RemoveFile(filename);
}

// When a script read() function returns a table
// And the table is an event
// Then no exception is thrown
// And read() returns true
TEST_F(SimuGenericTest, ReadReturnValue4) {
  std::string filename("/tmp/good_read.lua");
  CreateScript(filename, "function init()\n"
                         "end\n"
                         "function read()\n"
                         "return { _type=65559,\n"
                                  "service_id=1,\n"
                                  "ctime=1536659255,\n"
                                  "host_id=2,\n"
                                  "element=23,\n"
                                  "category=1,\n"
                                  "description=\"Super description\"\n"
                         "}\n"
                         "end\n");
  QMap<QString, QVariant> conf;
  modules::loader l;
  l.load_file("./neb/10-neb.so");
  std::unique_ptr<luabinding> lb(new luabinding(
                     filename,
                     conf));
  std::shared_ptr<io::data> d;
  ASSERT_TRUE(lb->read(d));
  RemoveFile(filename);
  neb::service* svc(static_cast<neb::service*>(d.get()));
  ASSERT_TRUE(svc->type() == 65559);
  ASSERT_EQ(svc->host_id, 2);
  std::cout << "service description: " << svc->service_description.toStdString();
  ASSERT_TRUE(svc->service_description == "Super description");
}

// When a script read() function returns a table
// And the table is an event
// Then no exception is thrown
// And read() returns true
TEST_F(SimuGenericTest, ReadReturnCustomVariable) {
  std::string filename("/tmp/good_read.lua");
  CreateScript(filename, "function init()\n"
                         "end\n"
                         "function read()\n"
                         "  return {\n"
                         "    service_id=498,\n"
                         "    _type=65539,\n"
                         "    update_time=1538146454,\n"
                         "    modified=false,\n"
                         "    host_id=31,\n"
                         "    element=3,\n"
                         "    name=\"PROCESSNAME\",\n"
                         "    category=1,\n"
                         "    value=\"centengine\",\n"
                         "    default_value=\"centengine\"}\n"
                         "end\n");
  QMap<QString, QVariant> conf;
  modules::loader l;
  l.load_file("./neb/10-neb.so");
  std::unique_ptr<luabinding> lb(new luabinding(
                     filename,
                     conf));
  std::shared_ptr<io::data> d;
  ASSERT_TRUE(lb->read(d));
  RemoveFile(filename);
  neb::custom_variable* cv(static_cast<neb::custom_variable*>(d.get()));
  ASSERT_TRUE(cv->type() == 65539);
  ASSERT_EQ(cv->host_id, 31);
  ASSERT_TRUE(cv->enabled);
}
<|endoftext|>


<commit_before>#include <shogun/lib/HSet.h>
#include <stdio.h>

using namespace shogun;

int main(int argc, char** argv)
{
	init_shogun();
	double v[8] = {0.0,0.0,0.1,0.1,0.2,0.2,0.3,0.3};

	CHSet<double>* set = new CHSet<double>(2, 8);

	for (int i=0; i<8; i++)
		set->add(v[i]);

	set->remove(0.1);
	set->add(0.4);

	delete set;
	exit_shogun();
	return 0;
}

<commit_msg>minor fixes<commit_after>#include <shogun/lib/Set.h>
#include <stdio.h>

using namespace shogun;

int main(int argc, char** argv)
{
	init_shogun();
	double v[8] = {0.0,0.0,0.1,0.1,0.2,0.2,0.3,0.3};

	CSet<double>* set = new CSet<double>(2, 8);

	for (int i=0; i<8; i++)
		set->add(v[i]);

	set->remove(0.1);
	set->add(0.4);

	delete set;
	exit_shogun();
	return 0;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xsdvalidationhelper.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 20:33:22 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef EXTENSIONS_SOURCE_PROPCTRLR_XSDVALIDATIONHELPER_HXX
#define EXTENSIONS_SOURCE_PROPCTRLR_XSDVALIDATIONHELPER_HXX

#ifndef EXTENSIONS_SOURCE_PROPCTRLR_EFORMSHELPER_HXX
#include "eformshelper.hxx"
#endif
#ifndef EXTENSIONS_SOURCE_PROPCTRLR_XSDDATATYPES_HXX
#include "xsddatatypes.hxx"
#endif

/** === begin UNO includes === **/
#ifndef _COM_SUN_STAR_XSD_XDATATYPE_HPP_
#include <com/sun/star/xsd/XDataType.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
/** === end UNO includes === **/

#ifndef _RTL_REF_HXX_
#include <rtl/ref.hxx>
#endif

//........................................................................
namespace pcr
{
//........................................................................

    class XSDDataType;
    //====================================================================
    //= XSDValidationHelper
    //====================================================================
    class XSDValidationHelper : public EFormsHelper
    {
    private:
        bool    m_bInspectingFormattedField;
    public:
        bool    isInspectingFormattedField() const { return m_bInspectingFormattedField; }

    public:
        XSDValidationHelper(
            const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxIntrospectee,
            const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& _rxContextDocument
        );

        /** retrieves the names of all XForms models in the document the control lives in
        */
        void    getAvailableDataTypeNames( ::std::vector< ::rtl::OUString >& /* [out] */ _rNames ) const SAL_THROW(());

        /** retrieves a particular data type given by name
        */
        ::rtl::Reference< XSDDataType >
                getDataTypeByName( const ::rtl::OUString& _rName ) const SAL_THROW(());

        /** retrieves the DataType instance which the control model is currently validated against

            If there is a binding set at our control model, which at the same time acts as validator,
            and if this validator is bound to an XDataType, then this data type is retrieved here.
        */
        ::rtl::Reference< XSDDataType >
                getValidatingDataType( ) const SAL_THROW(());

        /** retrieves the name of the data type which the control model is currently validated against

            @seealso getValidatingDataType
        */
        ::rtl::OUString
                getValidatingDataTypeName( ) const SAL_THROW(());

        /** binds the validator to a new data type

            To be called with an active binding only.
        */
        void    setValidatingDataTypeByName( const ::rtl::OUString& _rName ) const SAL_THROW(());

        /** removes the data type given by name from the data type repository
        */
        bool    removeDataTypeFromRepository( const ::rtl::OUString& _rName ) const SAL_THROW(());

        /** creates a new data type, which is a clone of an existing data type
        */
        bool    cloneDataType( const ::rtl::Reference< XSDDataType >& _pDataType, const ::rtl::OUString& _rNewName ) const SAL_THROW(());

        /** retrieves the name of the basic data type which has the given class
        */
        ::rtl::OUString
                getBasicTypeNameForClass( sal_Int16 _eClass ) const SAL_THROW(());

        /** copy a data type from one model to another

            If a data type with the given name already exists in the target model, then nothing
            happens. In particular, the facets of the data type are not copied.
        */
        void    copyDataType( const ::rtl::OUString& _rFromModel, const ::rtl::OUString& _rToModel,
                    const ::rtl::OUString& _rDataTypeName ) const SAL_THROW(());

        /** finds (and sets) a default format for the formatted field we're inspecting,
            according to the current data type the control value is evaluated against
        */
        void findDefaultFormatForIntrospectee() SAL_THROW(());

    private:
        /** retrieves the data type repository associated with the current model
        */
        ::com::sun::star::uno::Reference< ::com::sun::star::xforms::XDataTypeRepository >
                getDataTypeRepository() const SAL_THROW((::com::sun::star::uno::Exception));

        /** retrieves the data type repository associated with any model
        */
        ::com::sun::star::uno::Reference< ::com::sun::star::xforms::XDataTypeRepository >
                getDataTypeRepository( const ::rtl::OUString& _rModelName ) const SAL_THROW((::com::sun::star::uno::Exception));

        /** retrieves the data type object for the given name
        */
        ::com::sun::star::uno::Reference< ::com::sun::star::xsd::XDataType >
            getDataType( const ::rtl::OUString& _rName ) const
                SAL_THROW((::com::sun::star::uno::Exception));

        /** retrieves the name of the basic data type which has the given class, in the given repository
        */
        ::rtl::OUString
                getBasicTypeNameForClass(
                    sal_Int16 _nClass,
                    ::com::sun::star::uno::Reference< ::com::sun::star::xforms::XDataTypeRepository > _rxRepository
                ) const SAL_THROW(());
    };

//........................................................................
} // namespace pcr
//........................................................................

#endif // EXTENSIONS_SOURCE_PROPCTRLR_XSDVALIDATIONHELPER_HXX

<commit_msg>INTEGRATION: CWS pbrwuno (1.4.16); FILE MERGED 2005/10/17 13:19:05 fs 1.4.16.1: #i53095# proper listener administration: allow multiple listeners per handler<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xsdvalidationhelper.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: vg $ $Date: 2006-03-14 11:35:02 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef EXTENSIONS_SOURCE_PROPCTRLR_XSDVALIDATIONHELPER_HXX
#define EXTENSIONS_SOURCE_PROPCTRLR_XSDVALIDATIONHELPER_HXX

#ifndef EXTENSIONS_SOURCE_PROPCTRLR_EFORMSHELPER_HXX
#include "eformshelper.hxx"
#endif
#ifndef EXTENSIONS_SOURCE_PROPCTRLR_XSDDATATYPES_HXX
#include "xsddatatypes.hxx"
#endif

/** === begin UNO includes === **/
#ifndef _COM_SUN_STAR_XSD_XDATATYPE_HPP_
#include <com/sun/star/xsd/XDataType.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
/** === end UNO includes === **/

#ifndef _RTL_REF_HXX_
#include <rtl/ref.hxx>
#endif

//........................................................................
namespace pcr
{
//........................................................................

    class XSDDataType;
    //====================================================================
    //= XSDValidationHelper
    //====================================================================
    class XSDValidationHelper : public EFormsHelper
    {
    private:
        bool    m_bInspectingFormattedField;
    public:
        bool    isInspectingFormattedField() const { return m_bInspectingFormattedField; }

    public:
        XSDValidationHelper(
            ::osl::Mutex& _rMutex,
            const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxIntrospectee,
            const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& _rxContextDocument
        );

        /** retrieves the names of all XForms models in the document the control lives in
        */
        void    getAvailableDataTypeNames( ::std::vector< ::rtl::OUString >& /* [out] */ _rNames ) const SAL_THROW(());

        /** retrieves a particular data type given by name
        */
        ::rtl::Reference< XSDDataType >
                getDataTypeByName( const ::rtl::OUString& _rName ) const SAL_THROW(());

        /** retrieves the DataType instance which the control model is currently validated against

            If there is a binding set at our control model, which at the same time acts as validator,
            and if this validator is bound to an XDataType, then this data type is retrieved here.
        */
        ::rtl::Reference< XSDDataType >
                getValidatingDataType( ) const SAL_THROW(());

        /** retrieves the name of the data type which the control model is currently validated against

            @seealso getValidatingDataType
        */
        ::rtl::OUString
                getValidatingDataTypeName( ) const SAL_THROW(());

        /** binds the validator to a new data type

            To be called with an active binding only.
        */
        void    setValidatingDataTypeByName( const ::rtl::OUString& _rName ) const SAL_THROW(());

        /** removes the data type given by name from the data type repository
        */
        bool    removeDataTypeFromRepository( const ::rtl::OUString& _rName ) const SAL_THROW(());

        /** creates a new data type, which is a clone of an existing data type
        */
        bool    cloneDataType( const ::rtl::Reference< XSDDataType >& _pDataType, const ::rtl::OUString& _rNewName ) const SAL_THROW(());

        /** retrieves the name of the basic data type which has the given class
        */
        ::rtl::OUString
                getBasicTypeNameForClass( sal_Int16 _eClass ) const SAL_THROW(());

        /** copy a data type from one model to another

            If a data type with the given name already exists in the target model, then nothing
            happens. In particular, the facets of the data type are not copied.
        */
        void    copyDataType( const ::rtl::OUString& _rFromModel, const ::rtl::OUString& _rToModel,
                    const ::rtl::OUString& _rDataTypeName ) const SAL_THROW(());

        /** finds (and sets) a default format for the formatted field we're inspecting,
            according to the current data type the control value is evaluated against
        */
        void findDefaultFormatForIntrospectee() SAL_THROW(());

    private:
        /** retrieves the data type repository associated with the current model
        */
        ::com::sun::star::uno::Reference< ::com::sun::star::xforms::XDataTypeRepository >
                getDataTypeRepository() const SAL_THROW((::com::sun::star::uno::Exception));

        /** retrieves the data type repository associated with any model
        */
        ::com::sun::star::uno::Reference< ::com::sun::star::xforms::XDataTypeRepository >
                getDataTypeRepository( const ::rtl::OUString& _rModelName ) const SAL_THROW((::com::sun::star::uno::Exception));

        /** retrieves the data type object for the given name
        */
        ::com::sun::star::uno::Reference< ::com::sun::star::xsd::XDataType >
            getDataType( const ::rtl::OUString& _rName ) const
                SAL_THROW((::com::sun::star::uno::Exception));

        /** retrieves the name of the basic data type which has the given class, in the given repository
        */
        ::rtl::OUString
                getBasicTypeNameForClass(
                    sal_Int16 _nClass,
                    ::com::sun::star::uno::Reference< ::com::sun::star::xforms::XDataTypeRepository > _rxRepository
                ) const SAL_THROW(());
    };

//........................................................................
} // namespace pcr
//........................................................................

#endif // EXTENSIONS_SOURCE_PROPCTRLR_XSDVALIDATIONHELPER_HXX

<|endoftext|>


<commit_before>#include "behavior.h"
#include <vector>
#include <string>
#include <math.h>
#include "util/input/input-map.h"
#include "util/input/input-source.h"
#include "command.h"
#include "util/debug.h"
#include "character.h"
#include "stage.h"
#include "util/funcs.h"

using namespace std;

namespace Mugen{

namespace PaintownUtil = ::Util;

Behavior::Behavior(){
}

Behavior::~Behavior(){
}

void Behavior::hit(Object * enemy){
}

DummyBehavior::DummyBehavior(){
}

void DummyBehavior::flip(){
}

vector<string> DummyBehavior::currentCommands(const Mugen::Stage & stage, Character * owner, const std::vector<Command*> & commands, bool reversed){
    vector<string> out;
    return out;
}

DummyBehavior::~DummyBehavior(){
}

HumanBehavior::HumanBehavior(InputMap<Mugen::Keys> right, InputMap<Mugen::Keys> left):
right(right),
left(left){
}

InputMap<Keys> & HumanBehavior::getInput(bool facingRight){
    if (facingRight){
        return right;
    }
    return left;
}

/* turned around so we have to swap forward/backward */
void HumanBehavior::flip(){
    bool forward = input.forward;
    input.forward = input.back;
    input.back = forward;
}

Mugen::Input HumanBehavior::updateInput(InputMap<Keys> & keys, Mugen::Input old){
    vector<InputMap<Keys>::InputEvent> eventsHold = InputManager::getEvents(keys, InputSource());
    for (vector<InputMap<Keys>::InputEvent>::iterator it = eventsHold.begin(); it != eventsHold.end(); it++){
        InputMap<Keys>::InputEvent event = *it;

        switch (event.out){
            /* the keys map already sets up left/right to be forward/backward */
            case Mugen::Right: old.forward = event.enabled; break;
            case Mugen::Left: old.back = event.enabled; break;
            case Mugen::Up: old.up = event.enabled; break;
            case Mugen::Down: old.down = event.enabled; break;
            case Mugen::A: old.a = event.enabled; break;
            case Mugen::B: old.b = event.enabled; break;
            case Mugen::C: old.c = event.enabled; break;
            case Mugen::X: old.x = event.enabled; break;
            case Mugen::Y: old.y = event.enabled; break;
            case Mugen::Z: old.z = event.enabled; break;
            case Mugen::Start: old.start = event.enabled; break;
            default: break;
        }
    }

    return old;
}

vector<string> HumanBehavior::currentCommands(const Mugen::Stage & stage, Character * owner, const vector<Command*> & commands, bool reversed){
    vector<string> out;

    // InputMap<Mugen::Keys>::Output output = InputManager::getMap(getInput(reversed));
    input = updateInput(getInput(reversed), input);

    for (vector<Command*>::const_iterator it = commands.begin(); it != commands.end(); it++){
        Command * command = *it;
        if (command->handle(input)){
            Global::debug(2) << "command: " << command->getName() << endl;
            out.push_back(command->getName());
        }
    }

    return out;

}

HumanBehavior::~HumanBehavior(){
}

RandomAIBehavior::RandomAIBehavior(){
}

void RandomAIBehavior::flip(){
}

static string randomCommand(const vector<Command*> & commands){
    if (commands.size() == 0){
        return "";
    }

    int choice = PaintownUtil::rnd(commands.size());
    return commands[choice]->getName();
}

vector<string> RandomAIBehavior::currentCommands(const Mugen::Stage & stage, Character * owner, const vector<Command*> & commands, bool reversed){
    vector<string> out;
    if (PaintownUtil::rnd(100) > 90){
        out.push_back(randomCommand(commands));
    }
    return out;
}

RandomAIBehavior::~RandomAIBehavior(){
}

LearningAIBehavior::LearningAIBehavior(int difficulty):
direction(Forward),
difficulty(difficulty),
dontMove(0){
    /* make walking more likely to begin with */
    moves["holdfwd"].points -= 10;
    moves["holdfwd"].minimumDistance = 999999;
    moves["holdfwd"].maximumDistance = 0;
    moves["holdback"].points -= 10;
    moves["holdback"].minimumDistance = 999999;
    moves["holdback"].maximumDistance = 0;

    /* this is just to give the AI a starting move that does nothing, this is
     * basically a noop. eventualy the AI will learn other moves to do.
     *
     * the name is something that the user can't write for a command (hopefully)
     */
    moves["not-possible+#$*(@#$"].points = 5;
}

/* the command with the most points will be chosen. points are tallied by
 * adding all the quantities associated with that move thus far. right now they are:
 *  - starting points is the number of times the move hit successfully
 *  - add points if the move is within range, where range is determined by the last
 *     successful hit for that command
 *  - add a random number of points to shake things up
 *  - subtract points if the move is out of range
 *  - subtract points based on the number of times the move has been tried
 *  - subtract points if the move has been done recently
 */
string LearningAIBehavior::selectBestCommand(int distance, const vector<Command*> & commands){
    Move * currentMove = NULL;
    string what = "";
    double points = 0;

    for (vector<Command*>::const_iterator it = commands.begin(); it != commands.end(); it++){
        string name = (*it)->getName();
        Move & move = moves[name];
        double morePoints = move.points + PaintownUtil::rnd(10);
        if (move.minimumDistance != -1){
            if (distance < move.maximumDistance + 10 && distance > move.minimumDistance - 10){
                morePoints += 2;
            } else if (distance > move.maximumDistance + 10){
                morePoints -= 3;
            }
        }

        morePoints -= log((double) move.attempts * 3);
        morePoints -= move.consecutive * 2;

        if (currentMove == NULL){
            currentMove = &move;
            what = name;
            points = morePoints;
        } else if (morePoints > points){
            currentMove = &move;
            what = name;
            points = morePoints;
        }
    }

    for (map<string, Move>::iterator it = moves.begin(); it != moves.end(); it++){
        Move & move = (*it).second;
        if (currentMove != &move){
            move.consecutive /= 2;
        }
    }

    currentMove->attempts += 1;
    currentMove->consecutive += 1;

    return what;
}

void LearningAIBehavior::flip(){
}

static LearningAIBehavior::Direction randomDirection(){
    int what = PaintownUtil::rnd(100);
    if (what > 70){
        return LearningAIBehavior::Forward;
    } else if (what > 40){
        return LearningAIBehavior::Backward;
    } else if (what > 20){
        return LearningAIBehavior::Stopped;
    } else {
        return LearningAIBehavior::Crouch;
    }
}

vector<string> LearningAIBehavior::currentCommands(const Mugen::Stage & stage, Character * owner, const vector<Command*> & commands, bool reversed){

    vector<string> out;

    /* maybe attack */
    if (PaintownUtil::rnd(200) < difficulty * 2){
        const Character * enemy = stage.getEnemy(owner);
        int xDistance = (int) fabs(owner->getX() - enemy->getX());
        string command = selectBestCommand(xDistance, commands);
        out.push_back(command);
        lastCommand = command;
        lastDistance = xDistance;
    } else {
        /* otherwise move around */
        dontMove += 1;
        if (direction == Forward){
            out.push_back("holdfwd");
        } else if (direction == Backward){
            out.push_back("holdback");
        } else if (direction == Crouch){
            out.push_back("holddown");
        } else if (direction == Stopped){
        }

        /* after keeping a direction for 40 ticks, maybe change directions */
        if (dontMove > 40 && PaintownUtil::rnd(10) > 8){
            direction = randomDirection();
            dontMove = 0;
        }

        /* make the AI jump sometimes */
        if (PaintownUtil::rnd(100) == 0){
            out.push_back("holdup");
        }
    }

    return out;
}

/* hit succeeded, reinforce learning behavior for that move */
void LearningAIBehavior::hit(Object * enemy){
    Move & move = moves[lastCommand];
    move.points += 1;
    if (move.points > 5){
        move.points = 5;
    }

    if (move.maximumDistance == -1 || lastDistance > move.maximumDistance){
        move.maximumDistance = lastDistance;
    }

    if (move.minimumDistance == -1 || lastDistance < move.minimumDistance){
        move.minimumDistance = lastDistance;
    }
}

LearningAIBehavior::~LearningAIBehavior(){
}

/* crummy regex parsing */
static vector<string> parseCommands(string stuff){
    vector<string> out;

    while (PaintownUtil::matchRegex(stuff, "\\s*(\\w+)")){
        string get;
        get = PaintownUtil::captureRegex(stuff, "\\s*(\\w+)",0);
        out.push_back(get);
        stuff = PaintownUtil::captureRegex(stuff, "\\s*\\w+,?\\s*(.*)", 0);
    }

    return out;
}

ScriptedBehavior::ScriptedBehavior(const Filesystem::AbsolutePath & path){
    ifstream file(path.path().c_str());
    while (file.good() && !file.eof()){

        char line[1024];
        file.getline(line, sizeof(line) - 1);
        line[sizeof(line) - 1] = '\0';
        string whole(line);

        if (PaintownUtil::matchRegex(whole, "\\d+\\s+")){
            int ticks = atoi(PaintownUtil::captureRegex(whole, "(\\d+)", 0).c_str());
            string command = PaintownUtil::captureRegex(whole, "\\d+\\s+(.*)", 0);
            vector<string> commands = parseCommands(command);
            actions.push_back(Action(ticks, commands));
            // Global::debug(0) << "Added action " << PaintownUtil::join(commands, ", ") << " for " << ticks << std::endl;
        } else if (PaintownUtil::matchRegex(whole, "\\d+\\s$")){
            int ticks = atoi(PaintownUtil::captureRegex(whole, "(\\d+)", 0).c_str());
            actions.push_back(Action(ticks, vector<string>()));
            // Global::debug(1) << "Added no action for " << ticks << std::endl;
        } else {
            string command = PaintownUtil::captureRegex(whole, "(\\w+)\\s*", 0);
            vector<string> commands = parseCommands(command);
            if (commands.size() > 0){
                actions.push_back(Action(1, commands));
            }
            // Global::debug(1) << "Added action " << command << " for 1" << std::endl;
        }
    }

    currentAction = actions.begin();
}

std::vector<std::string> ScriptedBehavior::currentCommands(const Stage & stage, Character * owner, const std::vector<Command*> & commands, bool reversed){
    vector<string> out;

    if (currentAction != actions.end()){
        Action & action = *currentAction;

        action.ticks -= 1;
        out = action.commands;

        if (action.ticks == 0){
            currentAction++;
        }
    }

    return out;
}

void ScriptedBehavior::flip(){
}

ScriptedBehavior::~ScriptedBehavior(){
}

}
<commit_msg>[mugen] throw an error if the script file cant be found<commit_after>#include "behavior.h"
#include <vector>
#include <string>
#include <math.h>
#include "util/input/input-map.h"
#include "util/input/input-source.h"
#include "command.h"
#include "util/debug.h"
#include "character.h"
#include "stage.h"
#include "util/funcs.h"

using namespace std;

namespace Mugen{

namespace PaintownUtil = ::Util;

Behavior::Behavior(){
}

Behavior::~Behavior(){
}

void Behavior::hit(Object * enemy){
}

DummyBehavior::DummyBehavior(){
}

void DummyBehavior::flip(){
}

vector<string> DummyBehavior::currentCommands(const Mugen::Stage & stage, Character * owner, const std::vector<Command*> & commands, bool reversed){
    vector<string> out;
    return out;
}

DummyBehavior::~DummyBehavior(){
}

HumanBehavior::HumanBehavior(InputMap<Mugen::Keys> right, InputMap<Mugen::Keys> left):
right(right),
left(left){
}

InputMap<Keys> & HumanBehavior::getInput(bool facingRight){
    if (facingRight){
        return right;
    }
    return left;
}

/* turned around so we have to swap forward/backward */
void HumanBehavior::flip(){
    bool forward = input.forward;
    input.forward = input.back;
    input.back = forward;
}

Mugen::Input HumanBehavior::updateInput(InputMap<Keys> & keys, Mugen::Input old){
    vector<InputMap<Keys>::InputEvent> eventsHold = InputManager::getEvents(keys, InputSource());
    for (vector<InputMap<Keys>::InputEvent>::iterator it = eventsHold.begin(); it != eventsHold.end(); it++){
        InputMap<Keys>::InputEvent event = *it;

        switch (event.out){
            /* the keys map already sets up left/right to be forward/backward */
            case Mugen::Right: old.forward = event.enabled; break;
            case Mugen::Left: old.back = event.enabled; break;
            case Mugen::Up: old.up = event.enabled; break;
            case Mugen::Down: old.down = event.enabled; break;
            case Mugen::A: old.a = event.enabled; break;
            case Mugen::B: old.b = event.enabled; break;
            case Mugen::C: old.c = event.enabled; break;
            case Mugen::X: old.x = event.enabled; break;
            case Mugen::Y: old.y = event.enabled; break;
            case Mugen::Z: old.z = event.enabled; break;
            case Mugen::Start: old.start = event.enabled; break;
            default: break;
        }
    }

    return old;
}

vector<string> HumanBehavior::currentCommands(const Mugen::Stage & stage, Character * owner, const vector<Command*> & commands, bool reversed){
    vector<string> out;

    // InputMap<Mugen::Keys>::Output output = InputManager::getMap(getInput(reversed));
    input = updateInput(getInput(reversed), input);

    for (vector<Command*>::const_iterator it = commands.begin(); it != commands.end(); it++){
        Command * command = *it;
        if (command->handle(input)){
            Global::debug(2) << "command: " << command->getName() << endl;
            out.push_back(command->getName());
        }
    }

    return out;

}

HumanBehavior::~HumanBehavior(){
}

RandomAIBehavior::RandomAIBehavior(){
}

void RandomAIBehavior::flip(){
}

static string randomCommand(const vector<Command*> & commands){
    if (commands.size() == 0){
        return "";
    }

    int choice = PaintownUtil::rnd(commands.size());
    return commands[choice]->getName();
}

vector<string> RandomAIBehavior::currentCommands(const Mugen::Stage & stage, Character * owner, const vector<Command*> & commands, bool reversed){
    vector<string> out;
    if (PaintownUtil::rnd(100) > 90){
        out.push_back(randomCommand(commands));
    }
    return out;
}

RandomAIBehavior::~RandomAIBehavior(){
}

LearningAIBehavior::LearningAIBehavior(int difficulty):
direction(Forward),
difficulty(difficulty),
dontMove(0){
    /* make walking more likely to begin with */
    moves["holdfwd"].points -= 10;
    moves["holdfwd"].minimumDistance = 999999;
    moves["holdfwd"].maximumDistance = 0;
    moves["holdback"].points -= 10;
    moves["holdback"].minimumDistance = 999999;
    moves["holdback"].maximumDistance = 0;

    /* this is just to give the AI a starting move that does nothing, this is
     * basically a noop. eventualy the AI will learn other moves to do.
     *
     * the name is something that the user can't write for a command (hopefully)
     */
    moves["not-possible+#$*(@#$"].points = 5;
}

/* the command with the most points will be chosen. points are tallied by
 * adding all the quantities associated with that move thus far. right now they are:
 *  - starting points is the number of times the move hit successfully
 *  - add points if the move is within range, where range is determined by the last
 *     successful hit for that command
 *  - add a random number of points to shake things up
 *  - subtract points if the move is out of range
 *  - subtract points based on the number of times the move has been tried
 *  - subtract points if the move has been done recently
 */
string LearningAIBehavior::selectBestCommand(int distance, const vector<Command*> & commands){
    Move * currentMove = NULL;
    string what = "";
    double points = 0;

    for (vector<Command*>::const_iterator it = commands.begin(); it != commands.end(); it++){
        string name = (*it)->getName();
        Move & move = moves[name];
        double morePoints = move.points + PaintownUtil::rnd(10);
        if (move.minimumDistance != -1){
            if (distance < move.maximumDistance + 10 && distance > move.minimumDistance - 10){
                morePoints += 2;
            } else if (distance > move.maximumDistance + 10){
                morePoints -= 3;
            }
        }

        morePoints -= log((double) move.attempts * 3);
        morePoints -= move.consecutive * 2;

        if (currentMove == NULL){
            currentMove = &move;
            what = name;
            points = morePoints;
        } else if (morePoints > points){
            currentMove = &move;
            what = name;
            points = morePoints;
        }
    }

    for (map<string, Move>::iterator it = moves.begin(); it != moves.end(); it++){
        Move & move = (*it).second;
        if (currentMove != &move){
            move.consecutive /= 2;
        }
    }

    currentMove->attempts += 1;
    currentMove->consecutive += 1;

    return what;
}

void LearningAIBehavior::flip(){
}

static LearningAIBehavior::Direction randomDirection(){
    int what = PaintownUtil::rnd(100);
    if (what > 70){
        return LearningAIBehavior::Forward;
    } else if (what > 40){
        return LearningAIBehavior::Backward;
    } else if (what > 20){
        return LearningAIBehavior::Stopped;
    } else {
        return LearningAIBehavior::Crouch;
    }
}

vector<string> LearningAIBehavior::currentCommands(const Mugen::Stage & stage, Character * owner, const vector<Command*> & commands, bool reversed){

    vector<string> out;

    /* maybe attack */
    if (PaintownUtil::rnd(200) < difficulty * 2){
        const Character * enemy = stage.getEnemy(owner);
        int xDistance = (int) fabs(owner->getX() - enemy->getX());
        string command = selectBestCommand(xDistance, commands);
        out.push_back(command);
        lastCommand = command;
        lastDistance = xDistance;
    } else {
        /* otherwise move around */
        dontMove += 1;
        if (direction == Forward){
            out.push_back("holdfwd");
        } else if (direction == Backward){
            out.push_back("holdback");
        } else if (direction == Crouch){
            out.push_back("holddown");
        } else if (direction == Stopped){
        }

        /* after keeping a direction for 40 ticks, maybe change directions */
        if (dontMove > 40 && PaintownUtil::rnd(10) > 8){
            direction = randomDirection();
            dontMove = 0;
        }

        /* make the AI jump sometimes */
        if (PaintownUtil::rnd(100) == 0){
            out.push_back("holdup");
        }
    }

    return out;
}

/* hit succeeded, reinforce learning behavior for that move */
void LearningAIBehavior::hit(Object * enemy){
    Move & move = moves[lastCommand];
    move.points += 1;
    if (move.points > 5){
        move.points = 5;
    }

    if (move.maximumDistance == -1 || lastDistance > move.maximumDistance){
        move.maximumDistance = lastDistance;
    }

    if (move.minimumDistance == -1 || lastDistance < move.minimumDistance){
        move.minimumDistance = lastDistance;
    }
}

LearningAIBehavior::~LearningAIBehavior(){
}

/* crummy regex parsing */
static vector<string> parseCommands(string stuff){
    vector<string> out;

    while (PaintownUtil::matchRegex(stuff, "\\s*(\\w+)")){
        string get;
        get = PaintownUtil::captureRegex(stuff, "\\s*(\\w+)",0);
        out.push_back(get);
        stuff = PaintownUtil::captureRegex(stuff, "\\s*\\w+,?\\s*(.*)", 0);
    }

    return out;
}

ScriptedBehavior::ScriptedBehavior(const Filesystem::AbsolutePath & path){
    if (!Storage::instance().exists(path)){
        ostringstream out;
        out << "Could not load script file '" << path.path() << "'";
        throw MugenException(out.str(), __FILE__, __LINE__);
    }

    ifstream file(path.path().c_str());
    while (file.good() && !file.eof()){

        char line[1024];
        file.getline(line, sizeof(line) - 1);
        line[sizeof(line) - 1] = '\0';
        string whole(line);

        if (PaintownUtil::matchRegex(whole, "\\d+\\s+")){
            int ticks = atoi(PaintownUtil::captureRegex(whole, "(\\d+)", 0).c_str());
            string command = PaintownUtil::captureRegex(whole, "\\d+\\s+(.*)", 0);
            vector<string> commands = parseCommands(command);
            actions.push_back(Action(ticks, commands));
            // Global::debug(0) << "Added action " << PaintownUtil::join(commands, ", ") << " for " << ticks << std::endl;
        } else if (PaintownUtil::matchRegex(whole, "\\d+\\s$")){
            int ticks = atoi(PaintownUtil::captureRegex(whole, "(\\d+)", 0).c_str());
            actions.push_back(Action(ticks, vector<string>()));
            // Global::debug(1) << "Added no action for " << ticks << std::endl;
        } else {
            string command = PaintownUtil::captureRegex(whole, "(\\w+)\\s*", 0);
            vector<string> commands = parseCommands(command);
            if (commands.size() > 0){
                actions.push_back(Action(1, commands));
            }
            // Global::debug(1) << "Added action " << command << " for 1" << std::endl;
        }
    }

    currentAction = actions.begin();
}

std::vector<std::string> ScriptedBehavior::currentCommands(const Stage & stage, Character * owner, const std::vector<Command*> & commands, bool reversed){
    vector<string> out;

    if (currentAction != actions.end()){
        Action & action = *currentAction;

        action.ticks -= 1;
        out = action.commands;

        if (action.ticks == 0){
            currentAction++;
        }
    }

    return out;
}

void ScriptedBehavior::flip(){
}

ScriptedBehavior::~ScriptedBehavior(){
}

}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "../lib.hh"
#include "concat_c.hh"
#include "contents.hh"
#include "vick-insert-mode/lib.hh"

namespace vick {
namespace open_line {

struct open_line_c : public change {
private:
    const move_ts num_lines;
    const move_t y;

public:
    open_line_c(move_ts num_lines, move_t y)
        : num_lines(num_lines)
        , y(y) {
        assert(num_lines != 0);
    }
    virtual bool is_overriding() const noexcept override { return true; }
    virtual void undo(contents& contents) override {
        if (num_lines < 0) {
            contents.cont.erase(contents.cont.begin() + y,
                                contents.cont.begin() + y -
                                    num_lines);
            // contents.y = y /*+ num_lines*/;
        } else {
            contents.cont.erase(contents.cont.begin() + y + 1,
                                contents.cont.begin() + y + 1 +
                                    num_lines);
            // contents.y = y + num_lines;
        }
        contents.y = y;
        contents.x = 0;
    }
    virtual void redo(contents& contents) override {
        if (num_lines < 0) {
            for (int x = 0; x > num_lines; x--)
                contents.cont.insert(contents.cont.begin() + y + x,
                                     "");
            contents.y = y /*+ num_lines*/;
        } else {
            for (int x = 1; x <= num_lines; x++)
                contents.cont.insert(contents.cont.begin() + y + x,
                                     "");
            contents.y = y + num_lines;
        }
        contents.x = 0;
    }
    virtual std::shared_ptr<change>
    regenerate(const contents& contents) const override {
        return std::make_shared<open_line_c>(num_lines, contents.y);
    }
};

boost::optional<std::shared_ptr<change> >
open_line_below(contents& contents, boost::optional<int> num) {
    if (num and num.get() == 0)
        return boost::none;
    std::shared_ptr<change> open_line =
        std::make_shared<open_line_c>(num ? num.get() : 1,
                                      contents.y);
    open_line->redo(contents);
    auto insert = insert_mode::enter_insert_mode(contents);
    if (insert) {
        auto list = {open_line, insert.get()};
        return boost::optional<std::shared_ptr<change> >(
            std::make_shared<concat_c>(list));
    } else {
        return open_line;
    }
}

boost::optional<std::shared_ptr<change> >
open_line_above(contents& contents, boost::optional<int> num) {
    return open_line_below(contents, num ? -num.get() : -1);
}
}
}
<commit_msg>Format<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "../lib.hh"
#include "concat_c.hh"
#include "contents.hh"
#include "vick-insert-mode/lib.hh"

namespace vick {
namespace open_line {

struct open_line_c : public change {
private:
    const move_ts num_lines;
    const move_t y;

public:
    open_line_c(move_ts num_lines, move_t y)
        : num_lines(num_lines)
        , y(y) {
        assert(num_lines != 0);
    }
    virtual bool is_overriding() const noexcept override {
        return true;
    }
    virtual void undo(contents& contents) override {
        if (num_lines < 0) {
            contents.cont.erase(contents.cont.begin() + y,
                                contents.cont.begin() + y -
                                    num_lines);
            // contents.y = y /*+ num_lines*/;
        } else {
            contents.cont.erase(contents.cont.begin() + y + 1,
                                contents.cont.begin() + y + 1 +
                                    num_lines);
            // contents.y = y + num_lines;
        }
        contents.y = y;
        contents.x = 0;
    }
    virtual void redo(contents& contents) override {
        if (num_lines < 0) {
            for (int x = 0; x > num_lines; x--)
                contents.cont.insert(contents.cont.begin() + y + x,
                                     "");
            contents.y = y /*+ num_lines*/;
        } else {
            for (int x = 1; x <= num_lines; x++)
                contents.cont.insert(contents.cont.begin() + y + x,
                                     "");
            contents.y = y + num_lines;
        }
        contents.x = 0;
    }
    virtual std::shared_ptr<change>
    regenerate(const contents& contents) const override {
        return std::make_shared<open_line_c>(num_lines, contents.y);
    }
};

boost::optional<std::shared_ptr<change> >
open_line_below(contents& contents, boost::optional<int> num) {
    if (num and num.get() == 0)
        return boost::none;
    std::shared_ptr<change> open_line =
        std::make_shared<open_line_c>(num ? num.get() : 1,
                                      contents.y);
    open_line->redo(contents);
    auto insert = insert_mode::enter_insert_mode(contents);
    if (insert) {
        auto list = {open_line, insert.get()};
        return boost::optional<std::shared_ptr<change> >(
            std::make_shared<concat_c>(list));
    } else {
        return open_line;
    }
}

boost::optional<std::shared_ptr<change> >
open_line_above(contents& contents, boost::optional<int> num) {
    return open_line_below(contents, num ? -num.get() : -1);
}
}
}
<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRA;NTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/
#include <osg/View>
#include <osg/Notify>

using namespace osg;

View::View()
{
    // osg::notify(osg::NOTICE)<<"Constructing osg::View"<<std::endl;

    setCamera(new osg::Camera);
    _camera->setProjectionMatrixAsPerspective(50.0f,1.4f,1.0f,10000.0f);
}

View::~View()
{
    // osg::notify(osg::NOTICE)<<"Destructing osg::View"<<std::endl;

    // detatch the cameras from this View to prevent dangling pointers
    for(Slaves::iterator itr = _slaves.begin();
        itr != _slaves.end();
        ++itr)
    {
        Slave& cd = *itr;
        cd._camera->setView(0);
        cd._camera->setCullCallback(0);
    }

    // osg::notify(osg::NOTICE)<<"Done destructing osg::View"<<std::endl;
}

void View::updateSlaves()
{
    for(unsigned int i=0; i<_slaves.size(); ++i)
    {
        updateSlave(i);
    }
}

void View::updateSlave(unsigned int i)
{
    if (i >= _slaves.size() || !_camera) return;

    Slave& slave = _slaves[i];

    if (slave._camera->getReferenceFrame()==osg::Transform::RELATIVE_RF)
    {
        slave._camera->setProjectionMatrix(_camera->getProjectionMatrix() * slave._projectionOffset);
        slave._camera->setViewMatrix(_camera->getViewMatrix() * slave._viewOffset);
    }

    slave._camera->inheritCullSettings(*_camera);
    if (_camera->getInheritanceMask() & osg::CullSettings::CLEAR_COLOR) slave._camera->setClearColor(_camera->getClearColor());
}

bool View::addSlave(osg::Camera* camera, const osg::Matrix& projectionOffset, const osg::Matrix& viewOffset)
{
    if (!camera) return false;

    camera->setView(this);

    unsigned int i = _slaves.size();

    _slaves.push_back(Slave(camera, projectionOffset, viewOffset));

    updateSlave(i);

    return true;
}

bool View::removeSlave(unsigned int pos)
{
    if (pos >= _slaves.size()) return false;

    _slaves[pos]._camera->setView(0);
    _slaves[pos]._camera->setCullCallback(0);

    _slaves.erase(_slaves.begin()+pos);

    return true;
}

View::Slave* View::findSlaveForCamera(osg::Camera* camera)
{
    if (_camera == camera) return 0;

    for(unsigned int i=0; i<_slaves.size(); ++i)
    {
        if (_slaves[i]._camera == camera) return &(_slaves[i]);
    }

    return 0;
}

<commit_msg>Changed the View's master camera projection matrix setting so that it is consistent with osgProducer::Viewer default setting.<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRA;NTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/
#include <osg/View>
#include <osg/Notify>

using namespace osg;

View::View()
{
    // osg::notify(osg::NOTICE)<<"Constructing osg::View"<<std::endl;

    setCamera(new osg::Camera);
#if 0
    _camera->setProjectionMatrixAsPerspective(50.0f,1.4f,1.0f,10000.0f);
#else
    _camera->setProjectionMatrixAsFrustum(-0.325, 0.325, -0.26, 0.26, 1.0f,10000.0f);
#endif
}

View::~View()
{
    // osg::notify(osg::NOTICE)<<"Destructing osg::View"<<std::endl;

    // detatch the cameras from this View to prevent dangling pointers
    for(Slaves::iterator itr = _slaves.begin();
        itr != _slaves.end();
        ++itr)
    {
        Slave& cd = *itr;
        cd._camera->setView(0);
        cd._camera->setCullCallback(0);
    }

    // osg::notify(osg::NOTICE)<<"Done destructing osg::View"<<std::endl;
}

void View::updateSlaves()
{
    for(unsigned int i=0; i<_slaves.size(); ++i)
    {
        updateSlave(i);
    }
}

void View::updateSlave(unsigned int i)
{
    if (i >= _slaves.size() || !_camera) return;

    Slave& slave = _slaves[i];

    if (slave._camera->getReferenceFrame()==osg::Transform::RELATIVE_RF)
    {
        slave._camera->setProjectionMatrix(_camera->getProjectionMatrix() * slave._projectionOffset);
        slave._camera->setViewMatrix(_camera->getViewMatrix() * slave._viewOffset);
    }

    slave._camera->inheritCullSettings(*_camera);
    if (_camera->getInheritanceMask() & osg::CullSettings::CLEAR_COLOR) slave._camera->setClearColor(_camera->getClearColor());
}

bool View::addSlave(osg::Camera* camera, const osg::Matrix& projectionOffset, const osg::Matrix& viewOffset)
{
    if (!camera) return false;

    camera->setView(this);

    unsigned int i = _slaves.size();

    _slaves.push_back(Slave(camera, projectionOffset, viewOffset));

    updateSlave(i);

    return true;
}

bool View::removeSlave(unsigned int pos)
{
    if (pos >= _slaves.size()) return false;

    _slaves[pos]._camera->setView(0);
    _slaves[pos]._camera->setCullCallback(0);

    _slaves.erase(_slaves.begin()+pos);

    return true;
}

View::Slave* View::findSlaveForCamera(osg::Camera* camera)
{
    if (_camera == camera) return 0;

    for(unsigned int i=0; i<_slaves.size(); ++i)
    {
        if (_slaves[i]._camera == camera) return &(_slaves[i]);
    }

    return 0;
}

<|endoftext|>