Commit 230f4b73 authored by mercury233's avatar mercury233

Merge branch 'server-link' into server

parents c39785e4 5c0e80e5
......@@ -12,6 +12,6 @@
/gframe/ygopro.ico
/gframe/ygopro.rc
/gframe/ygopro.aps
/gframe/dirent.h
ygopro
premake5.exe
premake5
language: cpp
dist: trusty
git:
submodules: false
addons:
ssh_known_hosts:
- github.com
apt:
packages:
- libevent-dev
- libsqlite3-dev
- liblua5.2-dev
before_install:
- git submodule update --init --recursive
- wget -O - https://github.com/premake/premake-core/releases/download/v5.0.0-alpha10/premake-5.0.0-alpha10-linux.tar.gz | tar zfx -
script:
- ./premake5 gmake
- cd build
- sed -i 's/-llua/-llua5.2/g' ygopro.make
- make config=release
## YGOPro(Server)
[![Build status](https://ci.appveyor.com/api/projects/status/qgkqi6o0wq7qn922/branch/server?svg=true)](https://ci.appveyor.com/project/zh99998/ygopro/branch/server)
[![Build Status](https://travis-ci.org/moecube/ygopro.svg?branch=server)](https://travis-ci.org/moecube/ygopro)
一个YGOPro的服务端版本,运行后自动建立主机,并开启端口供YGOPro客户端连接。
现用于[萌卡](https://mycard.moe/)[YGOPRO 233服](http://mercury233.me/ygosrv233/)
现用于[萌卡](https://mycard.moe/)[YGOPro 233服](http://mercury233.me/ygosrv233/)
### Linux下编译
* 需要以下组件或工具
* gcc
* premake4
* premake5
* libevent
* lua5.2
* sqlite3
* 可参考 https://github.com/mercury233/ygopro-server/wiki 中的脚本
* 可参考本项目 [.travis.yml](https://github.com/mycard/ygopro/blob/server/.travis.yml) 中的脚本
### Windows下编译
* 需要以下组件或工具
......@@ -21,7 +22,6 @@
* libevent
* lua5.2
* sqlite3
* dirent for windows
* 可参考本项目 [appveyor.yml](https://github.com/mycard/ygopro/blob/server/appveyor.yml) 中的脚本
### 运行
......
......@@ -16,13 +16,10 @@ install:
- tar xf lua-5.2.4.tar.gz
- move lua-5.2.4\src lua
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://www.sqlite.org/2016/sqlite-amalgamation-3150200.zip ; exit 0"
- 7z x sqlite-amalgamation-3150200.zip
- move sqlite-amalgamation-3150200 sqlite3
- bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://www.sqlite.org/2017/sqlite-amalgamation-3200000.zip ; exit 0"
- 7z x sqlite-amalgamation-3200000.zip
- move sqlite-amalgamation-3200000 sqlite3
- appveyor DownloadFile https://github.com/tronkko/dirent/raw/master/include/dirent.h
- move dirent.h gframe\
# let premake happy
- xcopy /E premake\* .
......@@ -48,4 +45,4 @@ cache:
- premake-5.0.0-alpha10-windows.zip
- libevent-2.0.22-stable.tar.gz
- lua-5.2.4.tar.gz
- sqlite-amalgamation-3150200.zip
- sqlite-amalgamation-3200000.zip
No preview for this file type
......@@ -153,7 +153,7 @@ void SGUITTGlyph::preload(u32 char_index, FT_Face face, video::IVideoDriver* dri
}
glyph_page = parent->getLastGlyphPageIndex();
u32 texture_side_length = page->texture->getOriginalSize().Width;
u32 texture_side_length = page->texture_size.Width;
core::vector2di page_position(
(page->used_slots % (texture_side_length / font_size)) * font_size,
(page->used_slots / (texture_side_length / font_size)) * font_size
......@@ -230,7 +230,7 @@ CGUITTFont* CGUITTFont::create(IrrlichtDevice *device, const io::path& filename,
//! Constructor.
CGUITTFont::CGUITTFont(IGUIEnvironment *env)
: use_monochrome(false), use_transparency(true), use_hinting(true), use_auto_hinting(true),
batch_load_size(1), Device(0), Environment(env), Driver(0), GlobalKerningWidth(0), GlobalKerningHeight(0) {
batch_load_size(1), Device(0), Environment(env), Driver(0), GlobalKerningWidth(0), GlobalKerningHeight(0), supposed_line_height(0) {
#ifdef _DEBUG
setDebugName("CGUITTFont");
#endif
......@@ -345,6 +345,24 @@ bool CGUITTFont::load(const io::path& filename, const u32 size, const bool antia
getGlyphIndexByChar((uchar32_t)0);
batch_load_size = old_size;
// Calculate the supposed line height of this font (of this size) --
// Not using FT_SizeMetric::ascender or height, but actually by testing some of the glyphs,
// to see what should give a reasonable not cluttered line height.
// The ascender or height info may as well just be arbitrary ones.
// Get the maximum font height. Unfortunately, we have to do this hack as
// Irrlicht will draw things wrong. In FreeType, the font size is the
// maximum size for a single glyph, but that glyph may hang "under" the
// draw line, increasing the total font height to beyond the set size.
// Irrlicht does not understand this concept when drawing fonts. Also, I
// add +1 to give it a 1 pixel blank border. This makes things like
// tooltips look nicer.
s32 test1 = getHeightFromCharacter((uchar32_t)'g') + 1;
s32 test2 = getHeightFromCharacter((uchar32_t)'j') + 1;
s32 test3 = getHeightFromCharacter((uchar32_t)0x55B5) + 1;
supposed_line_height = core::max_(test1, core::max_(test2, test3));
return true;
}
......@@ -443,9 +461,8 @@ CGUITTGlyphPage* CGUITTFont::createGlyphPage(const u8& pixel_mode) {
if (page_texture_size.Width > max_texture_size.Width || page_texture_size.Height > max_texture_size.Height)
page_texture_size = max_texture_size;
if (!page->createPageTexture(pixel_mode, page_texture_size))
// TODO: add error message?
return 0;
page->texture_size = page_texture_size;
page->pixel_mode = pixel_mode;
if (page) {
// Determine the number of glyph slots on the page and add it to the list of pages.
......@@ -522,7 +539,7 @@ void CGUITTFont::draw(const core::stringw& text, const core::rect<s32>& position
if (lineBreak) {
previousChar = 0;
offset.Y += font_metrics.ascender / 64;
offset.Y += supposed_line_height; //font_metrics.ascender / 64;
offset.X = position.UpperLeftCorner.X;
if (hcenter)
......@@ -577,20 +594,8 @@ core::dimension2d<u32> CGUITTFont::getDimension(const wchar_t* text) const {
}
core::dimension2d<u32> CGUITTFont::getDimension(const core::ustring& text) const {
// Get the maximum font height. Unfortunately, we have to do this hack as
// Irrlicht will draw things wrong. In FreeType, the font size is the
// maximum size for a single glyph, but that glyph may hang "under" the
// draw line, increasing the total font height to beyond the set size.
// Irrlicht does not understand this concept when drawing fonts. Also, I
// add +1 to give it a 1 pixel blank border. This makes things like
// tooltips look nicer.
s32 test1 = getHeightFromCharacter((uchar32_t)'g') + 1;
s32 test2 = getHeightFromCharacter((uchar32_t)'j') + 1;
s32 test3 = getHeightFromCharacter((uchar32_t)'_') + 1;
s32 max_font_height = core::max_(test1, core::max_(test2, test3));
core::dimension2d<u32> text_dimension(0, max_font_height);
core::dimension2d<u32> line(0, max_font_height);
core::dimension2d<u32> text_dimension(0, supposed_line_height);
core::dimension2d<u32> line(0, supposed_line_height);
uchar32_t previousChar = 0;
core::ustring::const_iterator iter = text.begin();
......@@ -619,7 +624,7 @@ core::dimension2d<u32> CGUITTFont::getDimension(const core::ustring& text) const
if (text_dimension.Width < line.Width)
text_dimension.Width = line.Width;
line.Width = 0;
line.Height = max_font_height;
line.Height = supposed_line_height;
continue;
}
line.Width += getWidthFromCharacter(p);
......@@ -812,8 +817,29 @@ void CGUITTFont::setInvisibleCharacters(const core::ustring& s) {
}
video::IImage* CGUITTFont::createTextureFromChar(const uchar32_t& ch) {
return 0;
u32 n = getGlyphIndexByChar(ch);
const SGUITTGlyph& glyph = Glyphs[n - 1];
CGUITTGlyphPage* page = Glyph_Pages[glyph.glyph_page];
if (page->dirty)
page->updateTexture();
video::ITexture* tex = page->texture;
// Acquire a read-only lock of the corresponding page texture.
void* ptr = tex->lock(video::ETLM_READ_ONLY);
video::ECOLOR_FORMAT format = tex->getColorFormat();
core::dimension2du tex_size = tex->getOriginalSize();
video::IImage* pageholder = Driver->createImageFromData(format, tex_size, ptr, true, false);
// Copy the image data out of the page texture.
core::dimension2du glyph_size(glyph.source_rect.getSize());
video::IImage* image = Driver->createImage(format, glyph_size);
pageholder->copyTo(image, core::position2di(0, 0), glyph.source_rect);
tex->unlock();
return image;
}
video::ITexture* CGUITTFont::getPageTextureByIndex(const u32& page_index) const {
......@@ -917,7 +943,7 @@ core::array<scene::ISceneNode*> CGUITTFont::addTextSceneNode(const wchar_t* text
if (line_break) {
previous_char = 0;
offset.Y -= tt_face->size->metrics.ascender / 64;
offset.Y -= supposed_line_height; //tt_face->size->metrics.ascender / 64;
offset.X = start_point.X;
if (center)
offset.X += (text_size.Width - getDimensionUntilEndOfLine(text + 1).Width) >> 1;
......
......@@ -143,6 +143,12 @@ public:
void updateTexture() {
if (!dirty) return;
if (!texture) {
if (!createPageTexture(pixel_mode, texture_size))
// TODO: add error message?
return;
}
void* ptr = texture->lock();
video::ECOLOR_FORMAT format = texture->getColorFormat();
core::dimension2du size = texture->getOriginalSize();
......@@ -176,6 +182,9 @@ public:
core::array<core::vector2di> render_positions;
core::array<core::recti> render_source_rects;
core::dimension2du texture_size;
u8 pixel_mode;
private:
core::array<const SGUITTGlyph*> glyph_to_be_paged;
video::IVideoDriver* driver;
......@@ -368,6 +377,7 @@ private:
s32 GlobalKerningWidth;
s32 GlobalKerningHeight;
s32 supposed_line_height;
core::ustring Invisible;
};
......
......@@ -47,7 +47,7 @@ typedef std::unordered_map<unsigned int, CardDataC>::const_iterator code_pointer
class ClientCard {
public:
/*
#ifndef YGOPRO_SERVER_MODE
irr::core::matrix4 mTransform;
irr::core::vector3df curPos;
irr::core::vector3df curRot;
......@@ -120,7 +120,7 @@ public:
static bool deck_sort_atk(code_pointer l1, code_pointer l2);
static bool deck_sort_def(code_pointer l1, code_pointer l2);
static bool deck_sort_name(code_pointer l1, code_pointer l2);
*/
#endif //YGOPRO_SERVER_MODE
};
}
......
......@@ -76,6 +76,13 @@ void ClientField::Clear() {
reposable_cards.clear();
attackable_cards.clear();
disabled_field = 0;
panel = 0;
hovered_card = 0;
clicked_card = 0;
highlighting_card = 0;
hovered_controler = 0;
hovered_location = 0;
hovered_sequence = 0;
deck_act = false;
grave_act = false;
remove_act = false;
......
......@@ -2,7 +2,6 @@
#define CLIENT_FIELD_H
#include "config.h"
/*
#include <vector>
#include <set>
......@@ -141,7 +140,7 @@ public:
};
}
*/
//special cards
#define CARD_MARINE_DOLPHIN 78734254
#define CARD_TWINKLE_MOSS 13857930
......
#ifndef __CONFIG_H
#define __CONFIG_H
#pragma once
#define _IRR_STATIC_LIB_
#define IRR_COMPILE_WITH_DX9_DEV_PACK
#ifdef _WIN32
#include <WinSock2.h>
#include <windows.h>
#ifdef _MSC_VER
#define myswprintf _swprintf
#else
#define myswprintf swprintf
#endif
#define socklen_t int
#else //_WIN32
#include <errno.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#define SD_BOTH 2
#define SOCKET int
#define closesocket close
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define SOCKADDR_IN sockaddr_in
#define SOCKADDR sockaddr
#define SOCKET_ERRNO() (errno)
#include <wchar.h>
#define myswprintf(buf, fmt, ...) swprintf(buf, 4096, fmt, ##__VA_ARGS__)
inline int _wtoi(const wchar_t * s) {
wchar_t * endptr;
return (int)wcstol(s, &endptr, 10);
}
#endif
/*
#include <irrlicht.h>
#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#endif
#include "CGUITTFont.h"
#include "CGUIImageButton.h"
*/
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <time.h>
#include "bufferio.h"
#include "mymutex.h"
#include "mysignal.h"
#include "mythread.h"
#include "../ocgcore/ocgapi.h"
#include "../ocgcore/card.h"
/*
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
*/
extern const unsigned short PRO_VERSION;
extern int enable_log;
extern bool exit_on_return;
extern bool open_file;
extern wchar_t open_file_name[256];
#endif
#ifndef __CONFIG_H
#define __CONFIG_H
#pragma once
#define _IRR_STATIC_LIB_
#define IRR_COMPILE_WITH_DX9_DEV_PACK
#ifdef _WIN32
#include <WinSock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#ifdef _MSC_VER
#define myswprintf _swprintf
#else
#define myswprintf swprintf
#endif
#define socklen_t int
#else //_WIN32
#include <errno.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <locale.h>
#define SD_BOTH 2
#define SOCKET int
#define closesocket close
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define SOCKADDR_IN sockaddr_in
#define SOCKADDR sockaddr
#define SOCKET_ERRNO() (errno)
#include <wchar.h>
#define myswprintf(buf, fmt, ...) swprintf(buf, 4096, fmt, ##__VA_ARGS__)
inline int _wtoi(const wchar_t * s) {
wchar_t * endptr;
return (int)wcstol(s, &endptr, 10);
}
#endif
#ifndef YGOPRO_SERVER_MODE
#include <irrlicht.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "CGUITTFont.h"
#include "CGUIImageButton.h"
#endif //YGOPRO_SERVER_MODE
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <time.h>
#include "bufferio.h"
#include "mymutex.h"
#include "mysignal.h"
#include "mythread.h"
#include "../ocgcore/ocgapi.h"
#include "../ocgcore/card.h"
#ifndef YGOPRO_SERVER_MODE
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#endif //YGOPRO_SERVER_MODE
extern const unsigned short PRO_VERSION;
extern int enable_log;
extern bool exit_on_return;
extern bool open_file;
extern wchar_t open_file_name[256];
#endif
......@@ -12,7 +12,11 @@ bool DataManager::LoadDB(const char* file) {
if(sqlite3_open_v2(file, &pDB, SQLITE_OPEN_READONLY, 0) != SQLITE_OK)
return Error(pDB);
sqlite3_stmt* pStmt;
#ifdef YGOPRO_SERVER_MODE
const char* sql = "select * from datas";
#else
const char* sql = "select * from datas,texts where datas.id=texts.id";
#endif
if(sqlite3_prepare_v2(pDB, sql, -1, &pStmt, 0) != SQLITE_OK)
return Error(pDB);
CardDataC cd;
......@@ -44,7 +48,7 @@ bool DataManager::LoadDB(const char* file) {
cd.attribute = sqlite3_column_int(pStmt, 9);
cd.category = sqlite3_column_int(pStmt, 10);
_datas.insert(std::make_pair(cd.code, cd));
/*
#ifndef YGOPRO_SERVER_MODE
len = BufferIO::DecodeUTF8((const char*)sqlite3_column_text(pStmt, 12), strBuffer);
if(len) {
cs.name = new wchar_t[len + 1];
......@@ -66,7 +70,7 @@ bool DataManager::LoadDB(const char* file) {
} else cs.desc[i - 14] = 0;
}
_strings.insert(std::make_pair(cd.code, cs));
*/
#endif //YGOPRO_SERVER_MODE
}
} while(step != SQLITE_DONE);
sqlite3_finalize(pStmt);
......
......@@ -96,7 +96,7 @@ void DeckBuilder::Terminate() {
mainGame->PopupElement(mainGame->wMainMenu);
mainGame->device->setEventReceiver(&mainGame->menuHandler);
mainGame->wACMessage->setVisible(false);
imageManager.ClearTexture();
mainGame->ClearTextures();
mainGame->scrFilter->setVisible(false);
int sel = mainGame->cbDBDecks->getSelected();
if(sel >= 0)
......@@ -216,6 +216,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
if(mainGame->chkCategory[i]->isChecked())
filter_effect |= filter;
mainGame->HideElement(mainGame->wCategories);
InstantSearch();
break;
}
case BUTTON_SIDE_OK: {
......@@ -224,6 +225,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
mainGame->env->addMessageBox(L"", dataManager.GetSysString(1410));
break;
}
mainGame->imgCard->setImage(imageManager.tCover[0]);
char deckbuf[1024];
char* pdeck = deckbuf;
BufferIO::WriteInt32(pdeck, deckManager.current_deck.main.size() + deckManager.current_deck.extra.size());
......@@ -307,6 +309,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
if (mainGame->btnMark[7]->isPressed())
filter_marks |= 0004;
mainGame->HideElement(mainGame->wLinkMarks);
InstantSearch();
break;
}
}
......@@ -327,8 +330,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
case irr::gui::EGET_EDITBOX_CHANGED: {
switch(id) {
case EDITBOX_KEYWORD: {
if(mainGame->gameConf.auto_search_limit >= 0 && (wcslen(mainGame->ebCardName->getText()) >= mainGame->gameConf.auto_search_limit))
StartFilter();
InstantSearch();
break;
}
}
......@@ -445,6 +447,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break;
}
}
InstantSearch();
break;
}
case COMBOBOX_SORTTYPE: {
......@@ -461,8 +464,13 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
mainGame->ebDefense->setEnabled(true);
}
}
InstantSearch();
break;
}
case COMBOBOX_ATTRIBUTE:
case COMBOBOX_RACE:
case COMBOBOX_LIMIT:
InstantSearch();
}
}
default: break;
......@@ -853,6 +861,10 @@ void DeckBuilder::FilterCards() {
}
SortList();
}
void DeckBuilder::InstantSearch() {
if(mainGame->gameConf.auto_search_limit >= 0 && (wcslen(mainGame->ebCardName->getText()) >= mainGame->gameConf.auto_search_limit))
StartFilter();
}
void DeckBuilder::ClearSearch() {
mainGame->cbCardType->setSelected(0);
mainGame->cbCardType2->setSelected(0);
......
......@@ -17,6 +17,7 @@ public:
void FilterCards();
void StartFilter();
void ClearFilter();
void InstantSearch();
void ClearSearch();
void SortList();
......
......@@ -746,10 +746,10 @@ void Game::DrawSpec() {
switch(showcard) {
case 1: {
driver->draw2DImage(imageManager.GetTexture(showcardcode), position2di(574, 150));
driver->draw2DImage(imageManager.tMask, recti(574, 150, 574 + (showcarddif > 177 ? 177 : showcarddif), 404),
recti(254 - showcarddif, 0, 254 - (showcarddif > 177 ? showcarddif - 177 : 0), 254), 0, 0, true);
driver->draw2DImage(imageManager.tMask, recti(574, 150, 574 + (showcarddif > CARD_IMG_WIDTH ? CARD_IMG_WIDTH : showcarddif), 404),
recti(CARD_IMG_HEIGHT - showcarddif, 0, CARD_IMG_HEIGHT - (showcarddif > CARD_IMG_WIDTH ? showcarddif - CARD_IMG_WIDTH : 0), CARD_IMG_HEIGHT), 0, 0, true);
showcarddif += 15;
if(showcarddif >= 254) {
if(showcarddif >= CARD_IMG_HEIGHT) {
showcard = 2;
showcarddif = 0;
}
......@@ -757,9 +757,9 @@ void Game::DrawSpec() {
}
case 2: {
driver->draw2DImage(imageManager.GetTexture(showcardcode), position2di(574, 150));
driver->draw2DImage(imageManager.tMask, recti(574 + showcarddif, 150, 761, 404), recti(0, 0, 177 - showcarddif, 254), 0, 0, true);
driver->draw2DImage(imageManager.tMask, recti(574 + showcarddif, 150, 761, 404), recti(0, 0, CARD_IMG_WIDTH - showcarddif, CARD_IMG_HEIGHT), 0, 0, true);
showcarddif += 15;
if(showcarddif >= 177) {
if(showcarddif >= CARD_IMG_WIDTH) {
showcard = 0;
}
break;
......@@ -777,7 +777,7 @@ void Game::DrawSpec() {
matManager.c2d[2] = (showcarddif << 24) | 0xffffff;
matManager.c2d[3] = (showcarddif << 24) | 0xffffff;
driver->draw2DImage(imageManager.GetTexture(showcardcode), recti(574, 154, 751, 404),
recti(0, 0, 177, 254), 0, matManager.c2d, true);
recti(0, 0, CARD_IMG_WIDTH, CARD_IMG_HEIGHT), 0, matManager.c2d, true);
if(showcarddif < 255)
showcarddif += 17;
break;
......@@ -788,7 +788,7 @@ void Game::DrawSpec() {
matManager.c2d[2] = (showcarddif << 25) | 0xffffff;
matManager.c2d[3] = (showcarddif << 25) | 0xffffff;
driver->draw2DImage(imageManager.GetTexture(showcardcode), recti(662 - showcarddif * 0.69685f, 277 - showcarddif, 662 + showcarddif * 0.69685f, 277 + showcarddif),
recti(0, 0, 177, 254), 0, matManager.c2d, true);
recti(0, 0, CARD_IMG_WIDTH, CARD_IMG_HEIGHT), 0, matManager.c2d, true);
if(showcarddif < 127)
showcarddif += 9;
break;
......@@ -803,12 +803,12 @@ void Game::DrawSpec() {
}
case 7: {
core::position2d<s32> corner[4];
float y = sin(showcarddif * 3.1415926f / 180.0f) * 254;
corner[0] = core::position2d<s32>(574 - (254 - y) * 0.3f, 404 - y);
corner[1] = core::position2d<s32>(751 + (254 - y) * 0.3f, 404 - y);
float y = sin(showcarddif * 3.1415926f / 180.0f) * CARD_IMG_HEIGHT;
corner[0] = core::position2d<s32>(574 - (CARD_IMG_HEIGHT - y) * 0.3f, 404 - y);
corner[1] = core::position2d<s32>(751 + (CARD_IMG_HEIGHT - y) * 0.3f, 404 - y);
corner[2] = core::position2d<s32>(574, 404);
corner[3] = core::position2d<s32>(751, 404);
irr::gui::Draw2DImageQuad(driver, imageManager.GetTexture(showcardcode), rect<s32>(0, 0, 177, 254), corner);
irr::gui::Draw2DImageQuad(driver, imageManager.GetTexture(showcardcode), rect<s32>(0, 0, CARD_IMG_WIDTH, CARD_IMG_HEIGHT), corner);
showcardp++;
showcarddif += 9;
if(showcarddif >= 90)
......@@ -1022,8 +1022,6 @@ void Game::WaitFrameSignal(int frame) {
frameSignal.Wait();
}
void Game::DrawThumb(code_pointer cp, position2di pos, std::unordered_map<int, int>* lflist) {
const int width = 44; //standard pic size, maybe it should be defined in game.h
const int height = 64;
int code = cp->first;
int lcode = cp->second.alias;
if(lcode == 0)
......@@ -1032,7 +1030,7 @@ void Game::DrawThumb(code_pointer cp, position2di pos, std::unordered_map<int, i
if(img == NULL)
return; //NULL->getSize() will cause a crash
dimension2d<u32> size = img->getOriginalSize();
driver->draw2DImage(img, rect<s32>(pos.X, pos.Y, pos.X + width, pos.Y + height), rect<s32>(0, 0, size.Width, size.Height));
driver->draw2DImage(img, rect<s32>(pos.X, pos.Y, pos.X + CARD_THUMB_WIDTH, pos.Y + CARD_THUMB_HEIGHT), rect<s32>(0, 0, size.Width, size.Height));
if(lflist->count(lcode)) {
switch((*lflist)[lcode]) {
......
......@@ -282,6 +282,7 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->wDeckEdit->setVisible(false);
mainGame->wFilter->setVisible(false);
mainGame->wSort->setVisible(false);
mainGame->stTip->setVisible(false);
mainGame->btnSideOK->setVisible(true);
if(mainGame->dInfo.player_type < 7)
mainGame->btnLeaveGame->setVisible(false);
......@@ -294,6 +295,7 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->deckBuilder.result_string[0] = L'0';
mainGame->deckBuilder.result_string[1] = 0;
mainGame->deckBuilder.results.clear();
mainGame->deckBuilder.hovered_code = 0;
mainGame->deckBuilder.is_draging = false;
mainGame->deckBuilder.is_starting_dragging = false;
mainGame->deckBuilder.pre_mainc = deckManager.current_deck.main.size();
......@@ -489,7 +491,6 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->btnEP->setVisible(false);
mainGame->btnShuffle->setVisible(false);
mainGame->wChat->setVisible(true);
mainGame->imgCard->setImage(imageManager.tCover[0]);
mainGame->device->setEventReceiver(&mainGame->dField);
if(!mainGame->dInfo.isTag) {
if(selftype > 1) {
......@@ -554,6 +555,7 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->btnCreateHost->setEnabled(true);
mainGame->btnJoinHost->setEnabled(true);
mainGame->btnJoinCancel->setEnabled(true);
mainGame->stTip->setVisible(false);
mainGame->device->setEventReceiver(&mainGame->menuHandler);
mainGame->ShowElement(mainGame->wLanWindow);
mainGame->gMutex.Unlock();
......@@ -777,6 +779,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
mainGame->btnCreateHost->setEnabled(true);
mainGame->btnJoinHost->setEnabled(true);
mainGame->btnJoinCancel->setEnabled(true);
mainGame->stTip->setVisible(false);
mainGame->device->setEventReceiver(&mainGame->menuHandler);
mainGame->ShowElement(mainGame->wLanWindow);
mainGame->gMutex.Unlock();
......
......@@ -115,6 +115,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
DuelClient::StopClient();
mainGame->dInfo.isStarted = false;
mainGame->device->setEventReceiver(&mainGame->menuHandler);
mainGame->stTip->setVisible(false);
mainGame->wCardImg->setVisible(false);
mainGame->wInfos->setVisible(false);
mainGame->wPhase->setVisible(false);
......
This diff is collapsed.
......@@ -2,17 +2,23 @@
#define GAME_H
#include "config.h"
//#include "client_field.h"
//#include "deck_con.h"
//#include "menu_handler.h"
#ifndef YGOPRO_SERVER_MODE
#include "client_field.h"
#include "deck_con.h"
#include "menu_handler.h"
#else
#include "netserver.h"
#endif //YGOPRO_SERVER_MODE
#include <unordered_map>
#include <vector>
#include <list>
namespace ygo {
#ifndef YGOPRO_SERVER_MODE
struct Config {
bool use_d3d;
bool use_image_scale;
unsigned short antialias;
unsigned short serverport;
unsigned char textfontsize;
......@@ -65,7 +71,7 @@ struct DuelInfo {
unsigned short time_limit;
unsigned short time_left[2];
};
/*
struct FadingUnit {
bool signalAction;
bool isFadein;
......@@ -77,14 +83,18 @@ struct FadingUnit {
irr::core::vector2di fadingLR;
irr::core::vector2di fadingDiff;
};
*/
#endif //YGOPRO_SERVER_MODE
class Game {
public:
bool Initialize();
//void MainLoop();
void MainServerLoop(int bDuel_mode, int lflist);
/*
#ifdef YGOPRO_SERVER_MODE
void MainServerLoop();
void LoadExpansionDB();
void AddDebugMsg(char* msgbuf);
#else
void MainLoop();
void BuildProjectionMatrix(irr::core::matrix4& mProjection, f32 left, f32 right, f32 bottom, f32 top, f32 znear, f32 zfar);
void InitStaticText(irr::gui::IGUIStaticText* pControl, u32 cWidth, u32 cHeight, irr::gui::CGUITTFont* font, const wchar_t* text);
void SetStaticText(irr::gui::IGUIStaticText* pControl, u32 cWidth, irr::gui::CGUITTFont* font, const wchar_t* text, u32 pos = 0);
......@@ -116,19 +126,17 @@ public:
void AddDebugMsg(char* msgbuf);
void ClearTextures();
void CloseDuelWindow();
*/
int LocalPlayer(int player);
const wchar_t* LocalName(int local_player);
/*
bool HasFocus(EGUI_ELEMENT_TYPE type) const {
//irr::gui::IGUIElement* focus = env->getFocus();
irr::gui::IGUIElement* focus = env->getFocus();
return focus && focus->hasType(type);
}
void SetWindowsIcon();
void SetWindowsIcon();
void FlashWindow();
*/
Mutex gMutex;
Mutex gBuffer;
......@@ -141,7 +149,7 @@ public:
Config gameConf;
DuelInfo dInfo;
/*std::list<FadingUnit> fadingList;
std::list<FadingUnit> fadingList;
std::vector<int> logParam;
std::wstring chatMsg[8];
......@@ -174,8 +182,7 @@ public:
bool is_building;
bool is_siding;
*/
/*
ClientField dField;
DeckBuilder deckBuilder;
MenuHandler menuHandler;
......@@ -428,25 +435,23 @@ public:
irr::gui::IGUIButton* btnChainWhenAvail;
//cancel or finish
irr::gui::IGUIButton* btnCancelOrFinish;
*/
#endif //YGOPRO_SERVER_MODE
};
extern Game* mainGame;
#ifdef YGOPRO_SERVER_MODE
extern unsigned short aServerPort;
extern unsigned int lflist;
extern unsigned char rule;
extern unsigned char mode;
extern unsigned char duel_rule;
extern bool no_check_deck;
extern bool no_shuffle_deck;
extern unsigned int start_lp;
extern unsigned short time_limit;
extern unsigned short replay_mode;
extern unsigned char start_hand;
extern unsigned char draw_count;
extern HostInfo game_info;
#endif
}
#define CARD_IMG_WIDTH 177
#define CARD_IMG_HEIGHT 254
#define CARD_THUMB_WIDTH 44
#define CARD_THUMB_HEIGHT 64
#define UEVENT_EXIT 0x1
#define UEVENT_TOWINDOW 0x2
......@@ -563,6 +568,8 @@ extern unsigned char draw_count;
#define SCROLL_FILTER 315
#define EDITBOX_KEYWORD 316
#define BUTTON_CLEAR_FILTER 317
#define COMBOBOX_ATTRIBUTE 318
#define COMBOBOX_RACE 319
#define BUTTON_REPLAY_START 320
#define BUTTON_REPLAY_PAUSE 321
#define BUTTON_REPLAY_STEP 322
......@@ -576,6 +583,7 @@ extern unsigned char draw_count;
#define BUTTON_CANCEL_SINGLEPLAY 352
#define CHECKBOX_AUTO_SEARCH 360
#define COMBOBOX_SORTTYPE 370
#define COMBOBOX_LIMIT 371
#define BUTTON_MARKS_FILTER 380
#define BUTTON_MARKERS_OK 381
......
......@@ -3,10 +3,9 @@
#include "data_manager.h"
#include <event2/thread.h>
int enable_log = 1;
int enable_log = 0;
#ifndef YGOPRO_SERVER_MODE
bool exit_on_return = false;
bool runasserver = true;
bool keep_on_return = false;
bool open_file = false;
wchar_t open_file_name[256] = L"";
......@@ -26,7 +25,6 @@ void GetParameterW(wchar_t* param, const char* arg) {
BufferIO::DecodeUTF8(arg, param);
#endif
}
/*
void ClickButton(irr::gui::IGUIElement* btn) {
irr::SEvent event;
event.EventType = irr::EET_GUI_EVENT;
......@@ -34,8 +32,12 @@ void ClickButton(irr::gui::IGUIElement* btn) {
event.GUIEvent.Caller = btn;
ygo::mainGame->device->postEventFromUser(event);
}
*/
#endif //YGOPRO_SERVER_MODE
int main(int argc, char* argv[]) {
#ifndef _WIN32
setlocale(LC_CTYPE, "UTF-8");
#endif
#ifdef _WIN32
#ifndef _DEBUG
wchar_t exepath[MAX_PATH];
......@@ -55,40 +57,53 @@ int main(int argc, char* argv[]) {
evthread_use_pthreads();
#endif //_WIN32
ygo::Game _game;
if (runasserver){
ygo::aServerPort=7911;
ygo::aServerPort=atoi(argv[1]);
ygo::lflist=atoi(argv[2]);
ygo::start_hand=0;
ygo::replay_mode=0;
if (argc>2) {
ygo::rule=atoi(argv[3]);
ygo::mode=atoi(argv[4]);
if (argv[5][0]=='T')
ygo::duel_rule=DEFAULT_DUEL_RULE-1;
else
ygo::duel_rule=DEFAULT_DUEL_RULE;
if (argv[6][0]=='T')
ygo::no_check_deck=true;
else
ygo::no_check_deck=false;
if (argv[7][0]=='T')
ygo::no_shuffle_deck=true;
else
ygo::no_shuffle_deck=false;
ygo::start_lp=atoi(argv[8]);
ygo::start_hand=atoi(argv[9]);
ygo::draw_count=atoi(argv[10]);
ygo::time_limit=atoi(argv[11]);
if (argc>12)
ygo::replay_mode=atoi(argv[12]);
}
ygo::mainGame = &_game;
ygo::mainGame->MainServerLoop(ygo::mode, ygo::lflist);
return 0;
#ifdef YGOPRO_SERVER_MODE
enable_log = 1;
ygo::aServerPort = 7911;
ygo::replay_mode = 0;
ygo::game_info.lflist = 0;
ygo::game_info.rule = 0;
ygo::game_info.mode = 0;
ygo::game_info.start_hand = 5;
ygo::game_info.start_lp = 8000;
ygo::game_info.draw_count = 1;
ygo::game_info.no_check_deck = false;
ygo::game_info.no_shuffle_deck = false;
ygo::game_info.duel_rule = DEFAULT_DUEL_RULE;
ygo::game_info.time_limit = 180;
if(argc > 1) {
ygo::aServerPort = atoi(argv[1]);
int lflist = atoi(argv[2]);
if(lflist < 0)
lflist = 999;
ygo::game_info.lflist = lflist;
ygo::game_info.rule = atoi(argv[3]);
int mode = atoi(argv[4]);
if(mode > 2)
mode = 0;
ygo::game_info.mode = mode;
if(argv[5][0] == 'T')
ygo::game_info.duel_rule = DEFAULT_DUEL_RULE - 1;
else
ygo::game_info.duel_rule = DEFAULT_DUEL_RULE;
if(argv[6][0] == 'T')
ygo::game_info.no_check_deck = true;
else
ygo::game_info.no_check_deck = false;
if(argv[7][0] == 'T')
ygo::game_info.no_shuffle_deck = true;
else
ygo::game_info.no_shuffle_deck = false;
ygo::game_info.start_lp = atoi(argv[8]);
ygo::game_info.start_hand = atoi(argv[9]);
ygo::game_info.draw_count = atoi(argv[10]);
ygo::game_info.time_limit = atoi(argv[11]);
ygo::replay_mode = atoi(argv[12]);
}
/*
ygo::mainGame = &_game;
ygo::mainGame->MainServerLoop();
return 0;
#else //YGOPRO_SERVER_MODE
ygo::mainGame = &_game;
if(!ygo::mainGame->Initialize())
return 0;
......@@ -183,8 +198,8 @@ int main(int argc, char* argv[]) {
#ifdef _WIN32
WSACleanup();
#else
#endif //_WIN32
*/
#endif //YGOPRO_SERVER_MODE
return EXIT_SUCCESS;
}
#include "image_manager.h"
#include "game.h"
namespace ygo {
......@@ -63,6 +64,100 @@ void ImageManager::RemoveTexture(int code) {
tMap.erase(tit);
}
}
// function by Warr1024, from https://github.com/minetest/minetest/issues/2419 , modified
void imageScaleNNAA(irr::video::IImage *src, irr::video::IImage *dest)
{
double sx, sy, minsx, maxsx, minsy, maxsy, area, ra, ga, ba, aa, pw, ph, pa;
u32 dy, dx;
irr::video::SColor pxl;
// Cache rectsngle boundaries.
double sw = src->getDimension().Width * 1.0;
double sh = src->getDimension().Height * 1.0;
// Walk each destination image pixel.
// Note: loop y around x for better cache locality.
irr::core::dimension2d<u32> dim = dest->getDimension();
for(dy = 0; dy < dim.Height; dy++)
for(dx = 0; dx < dim.Width; dx++) {
// Calculate floating-point source rectangle bounds.
minsx = dx * sw / dim.Width;
maxsx = minsx + sw / dim.Width;
minsy = dy * sh / dim.Height;
maxsy = minsy + sh / dim.Height;
// Total area, and integral of r, g, b values over that area,
// initialized to zero, to be summed up in next loops.
area = 0;
ra = 0;
ga = 0;
ba = 0;
aa = 0;
// Loop over the integral pixel positions described by those bounds.
for(sy = floor(minsy); sy < maxsy; sy++)
for(sx = floor(minsx); sx < maxsx; sx++) {
// Calculate width, height, then area of dest pixel
// that's covered by this source pixel.
pw = 1;
if(minsx > sx)
pw += sx - minsx;
if(maxsx < (sx + 1))
pw += maxsx - sx - 1;
ph = 1;
if(minsy > sy)
ph += sy - minsy;
if(maxsy < (sy + 1))
ph += maxsy - sy - 1;
pa = pw * ph;
// Get source pixel and add it to totals, weighted
// by covered area and alpha.
pxl = src->getPixel((u32)sx, (u32)sy);
area += pa;
ra += pa * pxl.getRed();
ga += pa * pxl.getGreen();
ba += pa * pxl.getBlue();
aa += pa * pxl.getAlpha();
}
// Set the destination image pixel to the average color.
if(area > 0) {
pxl.setRed(ra / area + 0.5);
pxl.setGreen(ga / area + 0.5);
pxl.setBlue(ba / area + 0.5);
pxl.setAlpha(aa / area + 0.5);
} else {
pxl.setRed(0);
pxl.setGreen(0);
pxl.setBlue(0);
pxl.setAlpha(0);
}
dest->setPixel(dx, dy, pxl);
}
}
irr::video::ITexture* ImageManager::GetTextureFromFile(char* file, s32 width, s32 height) {
if(mainGame->gameConf.use_image_scale) {
irr::video::ITexture* texture;
irr::video::IImage* srcimg = driver->createImageFromFile(file);
if(srcimg == NULL)
return NULL;
if(srcimg->getDimension() == irr::core::dimension2d<u32>(width, height)) {
texture = driver->addTexture(file, srcimg);
} else {
video::IImage *destimg = driver->createImage(srcimg->getColorFormat(), irr::core::dimension2d<u32>(width, height));
imageScaleNNAA(srcimg, destimg);
texture = driver->addTexture(file, destimg);
destimg->drop();
}
srcimg->drop();
return texture;
} else {
return driver->getTexture(file);
}
}
irr::video::ITexture* ImageManager::GetTexture(int code) {
if(code == 0)
return tUnknown;
......@@ -70,23 +165,22 @@ irr::video::ITexture* ImageManager::GetTexture(int code) {
if(tit == tMap.end()) {
char file[256];
sprintf(file, "expansions/pics/%d.jpg", code);
irr::video::ITexture* img = driver->getTexture(file);
irr::video::ITexture* img = GetTextureFromFile(file, CARD_IMG_WIDTH, CARD_IMG_HEIGHT);
if(img == NULL) {
sprintf(file, "pics/%d.jpg", code);
img = driver->getTexture(file);
img = GetTextureFromFile(file, CARD_IMG_WIDTH, CARD_IMG_HEIGHT);
}
if(img == NULL) {
if(img == NULL && !mainGame->gameConf.use_image_scale) {
tMap[code] = NULL;
return GetTextureThumb(code);
} else {
tMap[code] = img;
return img;
}
tMap[code] = img;
return (img == NULL) ? tUnknown : img;
}
if(tit->second)
return tit->second;
else
return GetTextureThumb(code);
return mainGame->gameConf.use_image_scale ? tUnknown : GetTextureThumb(code);
}
irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
if(code == 0)
......@@ -95,18 +189,21 @@ irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
if(tit == tThumb.end()) {
char file[256];
sprintf(file, "expansions/pics/thumbnail/%d.jpg", code);
irr::video::ITexture* img = driver->getTexture(file);
irr::video::ITexture* img = GetTextureFromFile(file, CARD_THUMB_WIDTH, CARD_THUMB_HEIGHT);
if(img == NULL) {
sprintf(file, "pics/thumbnail/%d.jpg", code);
img = driver->getTexture(file);
img = GetTextureFromFile(file, CARD_THUMB_WIDTH, CARD_THUMB_HEIGHT);
}
if(img == NULL) {
tThumb[code] = NULL;
return tUnknown;
} else {
tThumb[code] = img;
return img;
if(img == NULL && mainGame->gameConf.use_image_scale) {
sprintf(file, "expansions/pics/%d.jpg", code);
img = GetTextureFromFile(file, CARD_THUMB_WIDTH, CARD_THUMB_HEIGHT);
if(img == NULL) {
sprintf(file, "pics/%d.jpg", code);
img = GetTextureFromFile(file, CARD_THUMB_WIDTH, CARD_THUMB_HEIGHT);
}
}
tThumb[code] = img;
return (img == NULL) ? tUnknown : img;
}
if(tit->second)
return tit->second;
......@@ -120,18 +217,18 @@ irr::video::ITexture* ImageManager::GetTextureField(int code) {
if(tit == tFields.end()) {
char file[256];
sprintf(file, "expansions/pics/field/%d.png", code);
irr::video::ITexture* img = driver->getTexture(file);
irr::video::ITexture* img = GetTextureFromFile(file, 512, 512);
if(img == NULL) {
sprintf(file, "expansions/pics/field/%d.jpg", code);
img = driver->getTexture(file);
img = GetTextureFromFile(file, 512, 512);
}
if(img == NULL) {
sprintf(file, "pics/field/%d.png", code);
img = driver->getTexture(file);
img = GetTextureFromFile(file, 512, 512);
}
if(img == NULL) {
sprintf(file, "pics/field/%d.jpg", code);
img = driver->getTexture(file);
img = GetTextureFromFile(file, 512, 512);
if(img == NULL) {
tFields[code] = NULL;
return NULL;
......
......@@ -13,6 +13,7 @@ public:
void SetDevice(irr::IrrlichtDevice* dev);
void ClearTexture();
void RemoveTexture(int code);
irr::video::ITexture* GetTextureFromFile(char* file, s32 width, s32 height);
irr::video::ITexture* GetTexture(int code);
irr::video::ITexture* GetTextureThumb(int code);
irr::video::ITexture* GetTextureField(int code);
......
......@@ -250,7 +250,7 @@ Materials::Materials() {
mCard.DiffuseColor = 0xff000000;
mCard.ColorMaterial = irr::video::ECM_NONE;
mCard.MaterialType = irr::video::EMT_ONETEXTURE_BLEND;
// mCard.MaterialTypeParam = pack_textureBlendFunc(EBF_SRC_ALPHA, EBF_ONE_MINUS_SRC_ALPHA, EMFN_MODULATE_1X, EAS_VERTEX_COLOR);
mCard.MaterialTypeParam = pack_textureBlendFunc(EBF_SRC_ALPHA, EBF_ONE_MINUS_SRC_ALPHA, EMFN_MODULATE_1X, EAS_VERTEX_COLOR);
mTexture.AmbientColor = 0xffffffff;
mTexture.DiffuseColor = 0xff000000;
mTexture.ColorMaterial = irr::video::ECM_NONE;
......@@ -260,13 +260,13 @@ Materials::Materials() {
mBackLine.DiffuseColor = 0xc0000000;
mBackLine.AntiAliasing = EAAM_FULL_BASIC;
mBackLine.MaterialType = irr::video::EMT_ONETEXTURE_BLEND;
// mBackLine.MaterialTypeParam = pack_textureBlendFunc(EBF_SRC_ALPHA, EBF_ONE_MINUS_SRC_ALPHA, EMFN_MODULATE_1X, EAS_VERTEX_COLOR);
mBackLine.MaterialTypeParam = pack_textureBlendFunc(EBF_SRC_ALPHA, EBF_ONE_MINUS_SRC_ALPHA, EMFN_MODULATE_1X, EAS_VERTEX_COLOR);
mBackLine.Thickness = 2;
mSelField.ColorMaterial = irr::video::ECM_NONE;
mSelField.AmbientColor = 0xffffffff;
mSelField.DiffuseColor = 0xff000000;
mSelField.MaterialType = irr::video::EMT_ONETEXTURE_BLEND;
// mSelField.MaterialTypeParam = pack_textureBlendFunc(EBF_SRC_ALPHA, EBF_ONE_MINUS_SRC_ALPHA, EMFN_MODULATE_1X, EAS_VERTEX_COLOR);
mSelField.MaterialTypeParam = pack_textureBlendFunc(EBF_SRC_ALPHA, EBF_ONE_MINUS_SRC_ALPHA, EMFN_MODULATE_1X, EAS_VERTEX_COLOR);
mOutLine.ColorMaterial = irr::video::ECM_AMBIENT;
mOutLine.DiffuseColor = 0xff000000;
mOutLine.Thickness = 2;
......@@ -276,7 +276,7 @@ Materials::Materials() {
mATK.DiffuseColor = 0x80000000;
mATK.setFlag(EMF_BACK_FACE_CULLING, FALSE);
mATK.MaterialType = irr::video::EMT_ONETEXTURE_BLEND;
// mATK.MaterialTypeParam = pack_textureBlendFunc(EBF_SRC_ALPHA, EBF_ONE_MINUS_SRC_ALPHA, EMFN_MODULATE_1X, EAS_VERTEX_COLOR);
mATK.MaterialTypeParam = pack_textureBlendFunc(EBF_SRC_ALPHA, EBF_ONE_MINUS_SRC_ALPHA, EMFN_MODULATE_1X, EAS_VERTEX_COLOR);
}
void Materials::GenArrow(float y) {
float ay = 1.0f;
......
......@@ -213,9 +213,6 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
mainGame->btnReplayStep->setVisible(false);
mainGame->btnReplayUndo->setVisible(false);
mainGame->wPhase->setVisible(true);
mainGame->dField.panel = 0;
mainGame->dField.hovered_card = 0;
mainGame->dField.clicked_card = 0;
mainGame->dField.Clear();
mainGame->HideElement(mainGame->wReplay);
mainGame->device->setEventReceiver(&mainGame->dField);
......@@ -305,11 +302,11 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
myswprintf(infobuf, L"%d/%d/%d %02d:%02d:%02d\n", st->tm_year + 1900, st->tm_mon + 1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec);
repinfo.append(infobuf);
wchar_t namebuf[4][20];
BufferIO::CopyWStr((unsigned short*)&ReplayMode::cur_replay.replay_data[0], namebuf[0], 20);
BufferIO::CopyWStr((unsigned short*)&ReplayMode::cur_replay.replay_data[40], namebuf[1], 20);
ReplayMode::cur_replay.ReadName(namebuf[0]);
ReplayMode::cur_replay.ReadName(namebuf[1]);
if(ReplayMode::cur_replay.pheader.flag & REPLAY_TAG) {
BufferIO::CopyWStr((unsigned short*)&ReplayMode::cur_replay.replay_data[80], namebuf[2], 20);
BufferIO::CopyWStr((unsigned short*)&ReplayMode::cur_replay.replay_data[120], namebuf[3], 20);
ReplayMode::cur_replay.ReadName(namebuf[2]);
ReplayMode::cur_replay.ReadName(namebuf[3]);
}
if(ReplayMode::cur_replay.pheader.flag & REPLAY_TAG)
myswprintf(infobuf, L"%ls\n%ls\n===VS===\n%ls\n%ls\n", namebuf[0], namebuf[1], namebuf[2], namebuf[3]);
......
......@@ -13,53 +13,52 @@ char NetServer::net_server_read[0x2000];
char NetServer::net_server_write[0x2000];
unsigned short NetServer::last_sent = 0;
#ifdef YGOPRO_SERVER_MODE
extern unsigned short replay_mode;
extern HostInfo game_info;
void NetServer::Initduel(int bDuel_mode, int lflist)
void NetServer::InitDuel()
{
CTOS_CreateGame* pkt = new CTOS_CreateGame;
pkt->info.mode=MODE_SINGLE;
if(bDuel_mode == MODE_SINGLE) {
duel_mode = new SingleDuel(false);
duel_mode->etimer = event_new(net_evbase, 0, EV_TIMEOUT | EV_PERSIST, SingleDuel::SingleTimer, duel_mode);
} else if(bDuel_mode == MODE_MATCH) {
duel_mode = new SingleDuel(true);
duel_mode->etimer = event_new(net_evbase, 0, EV_TIMEOUT | EV_PERSIST, SingleDuel::SingleTimer, duel_mode);
} else if(bDuel_mode == MODE_TAG) {
duel_mode = new TagDuel();
duel_mode->etimer = event_new(net_evbase, 0, EV_TIMEOUT | EV_PERSIST, TagDuel::TagTimer, duel_mode);
}
if(pkt->info.rule > 3)
pkt->info.rule = 0;
if(pkt->info.mode > 2)
pkt->info.mode = 0;
unsigned int hash = 0;
pkt->info.lflist = deckManager._lfList[lflist].hash;
if(game_info.mode == MODE_SINGLE) {
duel_mode = new SingleDuel(false);
duel_mode->etimer = event_new(net_evbase, 0, EV_TIMEOUT | EV_PERSIST, SingleDuel::SingleTimer, duel_mode);
} else if(game_info.mode == MODE_MATCH) {
duel_mode = new SingleDuel(true);
duel_mode->etimer = event_new(net_evbase, 0, EV_TIMEOUT | EV_PERSIST, SingleDuel::SingleTimer, duel_mode);
} else if(game_info.mode == MODE_TAG) {
duel_mode = new TagDuel();
duel_mode->etimer = event_new(net_evbase, 0, EV_TIMEOUT | EV_PERSIST, TagDuel::TagTimer, duel_mode);
}
for(auto lfit = deckManager._lfList.begin(); lfit != deckManager._lfList.end(); ++lfit) {
if(pkt->info.lflist == lfit->hash) {
hash = pkt->info.lflist;
break;
}
}
CTOS_CreateGame* pkt = new CTOS_CreateGame;
pkt->info.mode = game_info.mode;
pkt->info.start_hand = game_info.start_hand;
pkt->info.start_lp = game_info.start_lp;
pkt->info.draw_count = game_info.draw_count;
pkt->info.no_check_deck = game_info.no_check_deck;
pkt->info.no_shuffle_deck = game_info.no_shuffle_deck;
pkt->info.duel_rule = game_info.duel_rule;
pkt->info.rule = game_info.rule;
pkt->info.time_limit = game_info.time_limit;
if(!hash)
pkt->info.lflist = deckManager._lfList[0].hash;
if(lflist == -1)
pkt->info.lflist = 0;
duel_mode->host_info = pkt->info;
BufferIO::CopyWStr(pkt->name, duel_mode->name, 20);
BufferIO::CopyWStr(pkt->pass, duel_mode->pass, 20);
// duel_mode->JoinGame(dp, 0, true);
// StartBroadcast();
if(game_info.lflist == 999)
pkt->info.lflist = 0;
else if(game_info.lflist >= deckManager._lfList.size())
pkt->info.lflist = deckManager._lfList[0].hash;
else
pkt->info.lflist = deckManager._lfList[game_info.lflist].hash;
duel_mode->host_info = pkt->info;
BufferIO::CopyWStr(pkt->name, duel_mode->name, 20);
BufferIO::CopyWStr(pkt->pass, duel_mode->pass, 20);
}
unsigned short NetServer::StartServer(unsigned short port) {
#else
bool NetServer::StartServer(unsigned short port) {
#endif //YGOPRO_SERVER_MODE
if(net_evbase)
return false;
net_evbase = event_base_new();
......@@ -78,13 +77,17 @@ unsigned short NetServer::StartServer(unsigned short port) {
net_evbase = 0;
return false;
}
evutil_socket_t fd=evconnlistener_get_fd(listener);
socklen_t addrlen=sizeof(struct sockaddr);
struct sockaddr_in addr;
getsockname(fd,(struct sockaddr*)&addr,&addrlen);
evconnlistener_set_error_cb(listener, ServerAcceptError);
Thread::NewThread(ServerThread, net_evbase);
#ifdef YGOPRO_SERVER_MODE
evutil_socket_t fd = evconnlistener_get_fd(listener);
socklen_t addrlen = sizeof(sockaddr);
sockaddr_in addr;
getsockname(fd, (sockaddr*)&addr, &addrlen);
return ntohs(addr.sin_port);
#else
return true;
#endif //YGOPRO_SERVER_MODE
}
bool NetServer::StartBroadcast() {
if(!net_evbase)
......
......@@ -14,7 +14,9 @@ class NetServer {
private:
static std::unordered_map<bufferevent*, DuelPlayer> users;
static unsigned short server_port;
#ifndef YGOPRO_SERVER_MODE
static event_base* net_evbase;
#endif
static event* broadcast_ev;
static evconnlistener* listener;
static DuelMode* duel_mode;
......@@ -23,9 +25,13 @@ private:
static unsigned short last_sent;
public:
#ifdef YGOPRO_SERVER_MODE
static event_base* net_evbase;
static void Initduel(int duel_mode, int lflist);
static void InitDuel();
static unsigned short StartServer(unsigned short port);
#else
static bool StartServer(unsigned short port);
#endif //YGOPRO_SERVER_MODE
static bool StartBroadcast();
static void StopServer();
static void StopBroadcast();
......@@ -70,6 +76,14 @@ public:
if(dp)
bufferevent_write(dp->bev, net_server_write, last_sent);
}
#ifdef YGOPRO_SERVER_MODE
static void ReSendToPlayers(DuelPlayer* dp1, DuelPlayer* dp2) {
if(dp1)
bufferevent_write(dp1->bev, net_server_write, last_sent);
if(dp2)
bufferevent_write(dp2->bev, net_server_write, last_sent);
}
#endif //YGOPRO_SERVER_MODE
};
}
......
......@@ -22,7 +22,6 @@ struct HostInfo {
unsigned char start_hand;
unsigned char draw_count;
unsigned short time_limit;
unsigned short replay_mode;
};
struct HostPacket {
unsigned short identifier;
......
......@@ -2,6 +2,8 @@ include "lzma"
project "ygopro"
kind "ConsoleApp"
defines { "YGOPRO_SERVER_MODE" }
files { "gframe.cpp", "config.h",
"game.cpp", "game.h",
......@@ -10,8 +12,7 @@ project "ygopro"
"replay.cpp", "replay.h",
"netserver.cpp", "netserver.h",
"single_duel.cpp", "single_duel.h",
"tag_duel.cpp", "tag_duel.h",
"**.cc", "**.c"}
"tag_duel.cpp", "tag_duel.h" }
includedirs { "../ocgcore" }
links { "ocgcore", "clzma", "sqlite3", "lua" , "event"}
......
......@@ -3,13 +3,13 @@
#include "../ocgcore/card.h"
#include <algorithm>
#include "lzma/LzmaLib.h"
#include <sstream>
namespace ygo {
#ifdef YGOPRO_SERVER_MODE
extern unsigned short aServerPort;
extern unsigned short replay_mode;
#endif
Replay::Replay() {
is_recording = false;
is_replaying = false;
......@@ -20,157 +20,155 @@ Replay::~Replay() {
delete[] replay_data;
delete[] comp_data;
}
std::wstring SA2W(std::string& strA)
{
setlocale(LC_ALL, "chs");
const char* _Source = strA.c_str();
size_t _Dsize = strA.size() + 1;
wchar_t *_Dest = new wchar_t[_Dsize];
wmemset(_Dest, 0, _Dsize);
mbstowcs(_Dest,_Source,_Dsize);
std::wstring result = _Dest;
delete []_Dest;
setlocale(LC_ALL, "C");
return result;
}
void Replay::BeginRecord() {
if (ygo::replay_mode>0) {
#ifdef YGOPRO_SERVER_MODE
if(replay_mode > 0) {
#endif
#ifdef _WIN32
if(is_recording)
CloseHandle(recording_fp);
std::stringstream ss;
ss<<ygo::aServerPort;
std::string ssss;
ssss=ss.str();
std::wstring comPrefix = L"./replay/";
std::wstring comID =comPrefix+ SA2W(ssss)+L"Replay.yrp" ;
recording_fp = CreateFileW(comID.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);
if(recording_fp == INVALID_HANDLE_VALUE)
return;
if(is_recording)
CloseHandle(recording_fp);
#ifdef YGOPRO_SERVER_MODE
time_t nowtime = time(NULL);
struct tm *localedtime = localtime(&nowtime);
wchar_t tmppath[80];
wcsftime(tmppath, 80, L"./replay/%Y-%m-%d %H-%M-%S %%u.yrp", localedtime);
wchar_t path[80];
myswprintf(path, tmppath, aServerPort);
recording_fp = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);
#else
recording_fp = CreateFileW(L"./replay/_LastReplay.yrp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);
#endif //YGOPRO_SERVER_MODE
if(recording_fp == INVALID_HANDLE_VALUE)
return;
#else
if(is_recording)
fclose(fp);
time_t nowtime = time(NULL);
struct tm *localedtime = localtime(&nowtime);
char tmppath[40];
strftime(tmppath, 40, "./replay/%Y-%m-%d %H-%M-%S %%u.yrp", localedtime);
char path[40];
sprintf(path, tmppath, ygo::aServerPort);
fp = fopen(path, "wb");
if(!fp)
return;
if(is_recording)
fclose(fp);
#ifdef YGOPRO_SERVER_MODE
time_t nowtime = time(NULL);
struct tm *localedtime = localtime(&nowtime);
char tmppath[40];
strftime(tmppath, 40, "./replay/%Y-%m-%d %H-%M-%S %%u.yrp", localedtime);
char path[40];
sprintf(path, tmppath, aServerPort);
fp = fopen(path, "wb");
#else
fp = fopen("./replay/_LastReplay.yrp", "wb");
#endif //YGOPRO_SERVER_MODE
if(!fp)
return;
#endif
#ifdef YGOPRO_SERVER_MODE
}
#endif //YGOPRO_SERVER_MODE
pdata = replay_data;
is_recording = true;
}
void Replay::WriteHeader(ReplayHeader& header) {
pheader = header;
if (ygo::replay_mode>0) {
#ifdef YGOPRO_SERVER_MODE
if(replay_mode == 0) return;
#endif
#ifdef _WIN32
DWORD size;
WriteFile(recording_fp, &header, sizeof(header), &size, NULL);
DWORD size;
WriteFile(recording_fp, &header, sizeof(header), &size, NULL);
#else
fwrite(&header, sizeof(header), 1, fp);
fflush(fp);
fwrite(&header, sizeof(header), 1, fp);
fflush(fp);
#endif
}
}
void Replay::WriteData(const void* data, unsigned int length, bool flush) {
if(!is_recording)
return;
memcpy(pdata, data, length);
pdata += length;
if (ygo::replay_mode>0) {
#ifdef YGOPRO_SERVER_MODE
if(replay_mode == 0) return;
#endif
#ifdef _WIN32
DWORD size;
WriteFile(recording_fp, data, length, &size, NULL);
DWORD size;
WriteFile(recording_fp, data, length, &size, NULL);
#else
fwrite(data, length, 1, fp);
if(flush)
fflush(fp);
fwrite(data, length, 1, fp);
if(flush)
fflush(fp);
#endif
}
}
void Replay::WriteInt32(int data, bool flush) {
if(!is_recording)
return;
*((int*)(pdata)) = data;
pdata += 4;
if (ygo::replay_mode>0) {
#ifdef YGOPRO_SERVER_MODE
if(replay_mode == 0) return;
#endif
#ifdef _WIN32
DWORD size;
WriteFile(recording_fp, &data, sizeof(int), &size, NULL);
DWORD size;
WriteFile(recording_fp, &data, sizeof(int), &size, NULL);
#else
fwrite(&data, sizeof(int), 1, fp);
if(flush)
fflush(fp);
fwrite(&data, sizeof(int), 1, fp);
if(flush)
fflush(fp);
#endif
}
}
void Replay::WriteInt16(short data, bool flush) {
if(!is_recording)
return;
*((short*)(pdata)) = data;
pdata += 2;
if (ygo::replay_mode>0) {
#ifdef YGOPRO_SERVER_MODE
if(replay_mode == 0) return;
#endif
#ifdef _WIN32
DWORD size;
WriteFile(recording_fp, &data, sizeof(short), &size, NULL);
DWORD size;
WriteFile(recording_fp, &data, sizeof(short), &size, NULL);
#else
fwrite(&data, sizeof(short), 1, fp);
if(flush)
fflush(fp);
fwrite(&data, sizeof(short), 1, fp);
if(flush)
fflush(fp);
#endif
}
}
void Replay::WriteInt8(char data, bool flush) {
if(!is_recording)
return;
*pdata = data;
pdata++;
if (ygo::replay_mode>0) {
#ifdef YGOPRO_SERVER_MODE
if(replay_mode == 0) return;
#endif
#ifdef _WIN32
DWORD size;
WriteFile(recording_fp, &data, sizeof(char), &size, NULL);
DWORD size;
WriteFile(recording_fp, &data, sizeof(char), &size, NULL);
#else
fwrite(&data, sizeof(char), 1, fp);
if(flush)
fflush(fp);
fwrite(&data, sizeof(char), 1, fp);
if(flush)
fflush(fp);
#endif
}
}
void Replay::Flush() {
if(!is_recording)
return;
if (ygo::replay_mode>0) {
#ifdef YGOPRO_SERVER_MODE
if(replay_mode == 0) return;
#endif
#ifdef _WIN32
#else
fflush(fp);
fflush(fp);
#endif
}
}
void Replay::EndRecord() {
if(!is_recording)
return;
if (ygo::replay_mode>0) {
#ifdef YGOPRO_SERVER_MODE
if(replay_mode > 0) {
#endif
#ifdef _WIN32
CloseHandle(recording_fp);
CloseHandle(recording_fp);
#else
fclose(fp);
fclose(fp);
#endif
#ifdef YGOPRO_SERVER_MODE
}
#endif
pheader.datasize = pdata - replay_data;
pheader.flag |= REPLAY_COMPRESSED;
size_t propsize = 5;
......@@ -258,6 +256,13 @@ bool Replay::ReadNextResponse(unsigned char resp[64]) {
pdata += len;
return true;
}
void Replay::ReadName(wchar_t* data) {
if(!is_replaying)
return;
unsigned short buffer[20];
ReadData(buffer, 40);
BufferIO::CopyWStr(buffer, data, 20);
}
void Replay::ReadData(void* data, unsigned int length) {
if(!is_replaying)
return;
......
......@@ -36,6 +36,7 @@ public:
bool OpenReplay(const wchar_t* name);
static bool CheckReplay(const wchar_t* name);
bool ReadNextResponse(unsigned char resp[64]);
void ReadName(wchar_t* data);
void ReadHeader(ReplayHeader& header);
void ReadData(void* data, unsigned int length);
int ReadInt32();
......
......@@ -61,16 +61,16 @@ int ReplayMode::ReplayThread(void* param) {
int seed = rh.seed;
rnd.reset(seed);
if(rh.flag & REPLAY_TAG) {
cur_replay.ReadData(mainGame->dInfo.hostname, 40);
cur_replay.ReadData(mainGame->dInfo.hostname_tag, 40);
cur_replay.ReadData(mainGame->dInfo.clientname_tag, 40);
cur_replay.ReadData(mainGame->dInfo.clientname, 40);
cur_replay.ReadName(mainGame->dInfo.hostname);
cur_replay.ReadName(mainGame->dInfo.hostname_tag);
cur_replay.ReadName(mainGame->dInfo.clientname_tag);
cur_replay.ReadName(mainGame->dInfo.clientname);
mainGame->dInfo.isTag = true;
mainGame->dInfo.tag_player[0] = false;
mainGame->dInfo.tag_player[1] = false;
} else {
cur_replay.ReadData(mainGame->dInfo.hostname, 40);
cur_replay.ReadData(mainGame->dInfo.clientname, 40);
cur_replay.ReadName(mainGame->dInfo.hostname);
cur_replay.ReadName(mainGame->dInfo.clientname);
}
set_script_reader(default_script_reader);
set_card_reader((card_reader)DataManager::CardReader);
......@@ -185,6 +185,7 @@ int ReplayMode::ReplayThread(void* param) {
mainGame->closeDoneSignal.Wait();
mainGame->gMutex.Lock();
mainGame->ShowElement(mainGame->wReplay);
mainGame->stTip->setVisible(false);
mainGame->device->setEventReceiver(&mainGame->menuHandler);
mainGame->gMutex.Unlock();
if(exit_on_return)
......@@ -195,9 +196,6 @@ int ReplayMode::ReplayThread(void* param) {
void ReplayMode::Restart(bool refresh) {
end_duel(pduel);
mainGame->dInfo.isStarted = false;
mainGame->dField.panel = 0;
mainGame->dField.hovered_card = 0;
mainGame->dField.clicked_card = 0;
mainGame->dField.Clear();
//mainGame->device->setEventReceiver(&mainGame->dField);
cur_replay.Rewind();
......@@ -207,16 +205,16 @@ void ReplayMode::Restart(bool refresh) {
int seed = rh.seed;
rnd.reset(seed);
if(rh.flag & REPLAY_TAG) {
cur_replay.ReadData(mainGame->dInfo.hostname, 40);
cur_replay.ReadData(mainGame->dInfo.hostname_tag, 40);
cur_replay.ReadData(mainGame->dInfo.clientname_tag, 40);
cur_replay.ReadData(mainGame->dInfo.clientname, 40);
cur_replay.ReadName(mainGame->dInfo.hostname);
cur_replay.ReadName(mainGame->dInfo.hostname_tag);
cur_replay.ReadName(mainGame->dInfo.clientname_tag);
cur_replay.ReadName(mainGame->dInfo.clientname);
mainGame->dInfo.isTag = true;
mainGame->dInfo.tag_player[0] = false;
mainGame->dInfo.tag_player[1] = false;
} else {
cur_replay.ReadData(mainGame->dInfo.hostname, 40);
cur_replay.ReadData(mainGame->dInfo.clientname, 40);
cur_replay.ReadName(mainGame->dInfo.hostname);
cur_replay.ReadName(mainGame->dInfo.clientname);
}
//set_card_reader((card_reader)DataManager::CardReader);
//set_message_handler((message_handler)MessageHandler);
......
This diff is collapsed.
......@@ -49,7 +49,10 @@ protected:
unsigned char hand_result[2];
unsigned char last_response;
std::set<DuelPlayer*> observers;
std::set<DuelPlayer*> recorders;
#ifdef YGOPRO_SERVER_MODE
DuelPlayer* cache_recorder;
DuelPlayer* replay_recorder;
#endif
Replay last_replay;
bool match_mode;
int match_kill;
......
......@@ -78,9 +78,6 @@ int SingleMode::SinglePlayThread(void* param) {
mainGame->stText->setText(L"");
mainGame->scrCardText->setVisible(false);
mainGame->wPhase->setVisible(true);
mainGame->dField.panel = 0;
mainGame->dField.hovered_card = 0;
mainGame->dField.clicked_card = 0;
mainGame->dField.Clear();
mainGame->dInfo.isFirst = true;
mainGame->dInfo.isStarted = true;
......@@ -112,6 +109,7 @@ int SingleMode::SinglePlayThread(void* param) {
mainGame->closeDoneSignal.Wait();
mainGame->gMutex.Lock();
mainGame->ShowElement(mainGame->wSinglePlay);
mainGame->stTip->setVisible(false);
mainGame->device->setEventReceiver(&mainGame->menuHandler);
mainGame->gMutex.Unlock();
if(exit_on_return)
......
This diff is collapsed.
......@@ -46,7 +46,10 @@ protected:
DuelPlayer* pplayer[4];
DuelPlayer* cur_player[2];
std::set<DuelPlayer*> observers;
std::set<DuelPlayer*> recorders;
#ifdef YGOPRO_SERVER_MODE
DuelPlayer* cache_recorder;
DuelPlayer* replay_recorder;
#endif
bool ready[4];
Deck pdeck[4];
unsigned char hand_result[2];
......
This diff is collapsed.
Subproject commit 4291281e2cfd31b76354d04a283641c045532133
Subproject commit dfac0fbd59976a0612da49cc1b960290004df2ed
......@@ -15,10 +15,8 @@ solution "ygo"
configuration "macosx"
defines { "LUA_USE_MACOSX" }
includedirs { "/usr/local/include/*" }
libdirs { "/usr/local/lib", "/usr/X11/lib" }
buildoptions { "-stdlib=libc++" }
links {"OpenGL.framework","Cocoa.framework","IOKit.framework"}
includedirs { "/opt/local/include" }
libdirs { "/opt/local/lib" }
configuration "linux"
defines { "LUA_USE_LINUX" }
......@@ -47,7 +45,7 @@ solution "ygo"
defines { "_ITERATOR_DEBUG_LEVEL=0" }
configuration "Release"
--flags { "OptimizeSpeed" }
flags { "OptimizeSpeed" }
targetdir "bin/release"
include "ocgcore"
......
......@@ -3,28 +3,15 @@ solution "ygo"
language "C++"
objdir "obj"
configurations { "Debug", "Release" }
configurations { "Release", "Debug" }
configuration "windows"
defines { "WIN32", "_WIN32" }
configuration "bsd"
defines { "LUA_USE_POSIX" }
includedirs { "/usr/local/include" }
libdirs { "/usr/local/lib" }
configuration "macosx"
defines { "LUA_USE_MACOSX" }
includedirs { "/usr/local/include/*" }
libdirs { "/usr/local/lib", "/usr/X11/lib" }
buildoptions { "-stdlib=libc++" }
links {"OpenGL.framework","Cocoa.framework","IOKit.framework"}
configuration "linux"
defines { "LUA_USE_LINUX" }
configuration "Release"
flags { "OptimizeSpeed" }
targetdir "bin/release"
configuration "Debug"
......@@ -33,6 +20,7 @@ solution "ygo"
targetdir "bin/debug"
configuration { "Release", "vs*" }
optimize "Speed"
flags { "StaticRuntime", "LinkTimeOptimization" }
disablewarnings { "4244", "4267", "4838", "4577", "4819", "4018", "4996", "4477" }
......
Subproject commit 03638f34b137314e29aa4c83e703029224ee0ac3
Subproject commit 5f67c18822546bb7182c9c5a6567d42ecfe7592d
......@@ -584,6 +584,7 @@
!setname 0x3b 真红眼 レッドアイズ
!setname 0x3c 爬虫妖 レプティレス
!setname 0x3d 六武众 六武衆
!setname 0x103d 影六武众 影六武衆
!setname 0x3e 异虫 ワーム
!setname 0x3f 救世 セイヴァー
!setname 0x40 被封印 封印されし
......@@ -810,8 +811,8 @@
#!setname 0xec 魔界 魔界
!setname 0x10ec 魔界剧团 魔界劇団
!setname 0x20ec 魔界台本 魔界台本
!setname 0xed底恐魔 Subterror
!setname 0x10ed底恐魔 巨魔 Subterror Behemoth
!setname 0xed中族 サブテラー
!setname 0x10ed中族邪界 サブテラーマリス
!setname 0xee 秘旋谍 SPYRAL
!setname 0x10ee 秘旋谍装备 SPYRAL GEAR
!setname 0x20ee 秘旋谍任务 SPYRAL MISSION
......@@ -843,3 +844,7 @@
!setname 0x103 幻变骚灵 オルターガイスト
!setname 0x104 机怪虫 クローラー
!setname 0x105 玄化 メタファイズ
!setname 0x106 复仇死者 ヴェンデット
!setname 0x107 方程式运动员 F.A.
!setname 0x108 魔弹 魔弾
!setname 0x109 天气 天気
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment