Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

[Release] IGCN Season 9.5 (src-x9.5 9.5.1.15) SRC (April/2016)

Joined
Aug 29, 2011
Messages
512
Reaction score
33
Someone could add to this muserver a custum that has in Zteam that I find very interesting to bonus players in events.

it's the MonsterSpawner.xml

in Red is define an item that when it is dropped will create a Temporary Spot
in Yellow is defined the monster that will spawn and also the quantity and the duration time.
in Green it is defined if the spot created will be private or not (if it is deprived only those who dropped the item can attack the monsters.
in Blue is defined if the party of whom the item drops will be able to attack.
in Orange is set if the guild of who drops the item will be able to attack.

<monsterspawner>
<!-- example, elite yeti -->
<item type="14" index="300">
<spawn monster="20" count="30" duration="60" />
<!-- rules for use this spot (false: any user can attack, true: only owner & by rules) -->
<private active="true">
<party>true</party>
<guild>false</guild>
</private>
</item>

<!-- example, mutant -->
<item type="14" index="301">
<spawn monster="62" count="30" duration="60" />
<!-- rules for use this spot (false: any user can attack, true: only owner & by rules) -->
<private active="true">
<party>true</party>
<guild>false</guild>
</private>
</item>

<!-- example, fire golem -->
<item type="14" index="302">
<spawn monster="291" count="30" duration="60" />
<!-- rules for use this spot (false: any user can attack, true: only owner & by rules) -->
<private active="true">
<party>true</party>
<guild>false</guild>
</private>
</item>
</monsterspawner>


aqui fica os código que eu pegue da source da Zteam

MonsterSpawner.cpp

PHP:
#include "stdafx.h"
#include "MonsterSpawner.h"
#include "GameMain.h"
#include "..\pugixml\pugixml.hpp"

MonsterSpawnerMng* MonsterSpawnerMng::m_Instance = NULL;

MonsterSpawnerMng::MonsterSpawnerMng() {
    m_WorkPool.clear();
    //m_ItemData.clear();
}

MonsterSpawnerMng::~MonsterSpawnerMng() {
    // lifetime instance...
}

void MonsterSpawnerMng::Load() {
    m_Loaded = false;
    Init();
    Read(gDirPath.GetNewPath(FILE_CUSTOM_MONSTERSPAWNER));
}

void MonsterSpawnerMng::Init() {
    m_ItemData.clear();
}

void MonsterSpawnerMng::Read(const char *File) {
    using namespace pugi;
    xml_document Document;
    xml_parse_result Result = Document.load_file(File);
    if (Result.status != status_ok) {
        MsgBox("[MonsterSpawnerMng] File %s not found!", File);
        return;
    }
    xml_node nodeMain = Document.child("monsterspawner");
    for (xml_node nodeIt = nodeMain.child("item"); nodeIt; nodeIt = nodeIt.next_sibling()) {
        MonsterSpawnerItemInfo newItem = { 0 };
        newItem.itemCategory = nodeIt.attribute("type").as_int(-1);
        newItem.itemIndex = nodeIt.attribute("index").as_int(-1);
        newItem.spawnMonsterId = nodeIt.child("spawn").attribute("monster").as_int(-1);
        newItem.spawnMonsterCount = nodeIt.child("spawn").attribute("count").as_int(-1);
        newItem.spawnDuration = nodeIt.child("spawn").attribute("duration").as_int(-1);
        newItem.isPrivate = nodeIt.child("private").attribute("active").as_bool();
        newItem.isPrivateParty = nodeIt.child("private").child("party").text().as_bool();
        newItem.isPrivateGuild = nodeIt.child("private").child("guild").text().as_bool();
        m_ItemData.push_back(newItem);
    }
    LogAddTD("[MonsterSpawnerMng] loaded %d node(s)", m_ItemData.size());
    m_Loaded = true;
}

void MonsterSpawnerMng::procRun() {

    for (size_t i = 0; i < m_WorkPool.size(); i++) {

        if (m_WorkPool[i].isEmpty()) {
            continue;
        }
        if (m_WorkPool[i].isExpired()) {
            LogAddTD("[MonsterSpawnerMng] [%s] spot duration is expired, slot cleared",
                m_WorkPool[i].ownerName.c_str());
            m_WorkPool[i].clearSlot();
        }
    }
}

void MonsterSpawnerMng::procRegen(short MonsterIndex) {
    gObj[MonsterIndex].X = gObj[MonsterIndex].StartX;
    gObj[MonsterIndex].Y = gObj[MonsterIndex].StartY;
    gObj[MonsterIndex].MTX = gObj[MonsterIndex].X;
    gObj[MonsterIndex].MTY = gObj[MonsterIndex].Y;
    gObj[MonsterIndex].m_ActState.Emotion = 1;
    gObj[MonsterIndex].m_ActState.EmotionCount = 1;
}

bool MonsterSpawnerMng::procCreate(short UserIndex, int ItemCode) {
    MonsterSpawnerItemInfo* tmpItemInfo = getItemInfo(ItemCode);
    if (tmpItemInfo == NULL) {
        return false;
    }
    int tmpSlotIndex = getEmptySlot();
    if (tmpSlotIndex == -1) {
        MonsterSpawnerWorkNode newNode;
        newNode.setSlot(UserIndex, tmpItemInfo);
        m_WorkPool.push_back(newNode);
    } else {
        m_WorkPool[tmpSlotIndex].setSlot(UserIndex, tmpItemInfo);
    }
    LogAddTD("[MonsterSpawnerMng] [%s][%s] spot has been created (monster: %d, count: %d, duration: %d, map: %d (%d:%d))",
        gObj[UserIndex].AccountID, gObj[UserIndex].Name, tmpItemInfo->spawnMonsterId, tmpItemInfo->spawnMonsterCount,
        tmpItemInfo->spawnDuration, gObj[UserIndex].MapNumber, gObj[UserIndex].X, gObj[UserIndex].Y);
    return true;
}

bool MonsterSpawnerMng::isPrivate(short UserIndex, short MonsterIndex) {
    LPOBJ tmpAttacker = &gObj[UserIndex];
    LPOBJ tmpMonster = &gObj[MonsterIndex];
    LPOBJ tmpOwner = NULL;
    MonsterSpawnerWorkNode* tmpNode = NULL;
    MonsterSpawnerItemInfo* tmpItem = NULL;

    for (size_t i = 0; i < m_WorkPool.size(); i++) { // select node

        if (m_WorkPool[i].isMonster(MonsterIndex)) {
            tmpNode = &m_WorkPool[i];
            break;
        }
    }
    if (tmpNode == NULL) { // node not founded, spot unblocked
        return false;
    }
    if (tmpNode->isOwner(tmpAttacker->Name)) { // owner
        return false;
    }
    tmpItem = getItemInfo(tmpNode->itemCode);
    if (tmpItem == NULL) { // rules for node not founded, spot unblocked
        return false;
    }
    if (!tmpItem->isPrivate) { // spot not privated by rules
        return false;
    }
    for (int i = OBJ_STARTUSERINDEX; i < OBJMAX; i++) { // select live owner
        if (gObj[i].Connected >= PLAYER_PLAYING) {
            if (tmpNode->isOwner(gObj[i].Name)) {
                tmpOwner = &gObj[i];
                break;
            }
        }
    }
    if (tmpOwner == NULL) { // spot have owner, but owner is offline, cant check rules - block by rules
        MsgOutput(UserIndex, "Monster is privated by %s", tmpNode->ownerName.c_str());
        return true;
    }
    if (tmpItem->isPrivateParty && tmpOwner->PartyNumber >= 0) { // spot is not privated for party members
        if (tmpOwner->PartyNumber == tmpAttacker->PartyNumber) {
            return false;
        }
    }
    if (tmpItem->isPrivateGuild && tmpOwner->GuildNumber > 0) { // spot is not privated for guild members
        if (tmpOwner->GuildNumber == tmpAttacker->GuildNumber) {
            return false;
        }
    }
    MsgOutput(UserIndex, "Monster is privated by %s", tmpNode->ownerName.c_str());
    return true;
}

bool MonsterSpawnerMng::isEventMonster(short MonsterIndex) {

    for (size_t i = 0; i < m_WorkPool.size(); i++) {

        if (m_WorkPool[i].isMonster(MonsterIndex)) {
            return true;
        }
    }
    return false;
}

bool MonsterSpawnerMng::isKeyItem(int ItemCode) {
    if (getItemInfo(ItemCode) != NULL) {
        return true;
    }
    return false;
}

int MonsterSpawnerMng::getEmptySlot() {

    for (size_t i = 0; i < m_WorkPool.size(); i++) {

        if (m_WorkPool[i].isEmpty()) {
            return i;
        }
    }
    return -1;
}

MonsterSpawnerItemInfo* MonsterSpawnerMng::getItemInfo(int ItemCode) {
    if (!m_Loaded) {
        return NULL;
    }

    for (size_t i = 0; i < m_ItemData.size(); i++) {

        if (ITEMGET(m_ItemData[i].itemCategory, m_ItemData[i].itemIndex) == ItemCode) {
            return &m_ItemData[i];
        }
    }
    return NULL;
}

MonsterSpawner.h



PHP:
#pragma once

// import
#include "user.h"

// data
struct MonsterSpawnerItemInfo {
    short itemIndex;
    short itemCategory;
    short spawnMonsterId;
    short spawnMonsterCount;
    short spawnDuration;
    bool isPrivate;
    bool isPrivateParty;
    bool isPrivateGuild;
};

struct MonsterSpawnerWorkNode { // maybe better use class & ptr instance...
    MonsterSpawnerWorkNode() {
        ownerName.reserve(MAX_ACCOUNT_LEN + 1);
        monsterPool.clear();
        itemCode = -1;
        tickEnd = 0;
    }
    void setSlot(short UserIndex, MonsterSpawnerItemInfo* itemInfo) {
        if (UserIndex < 0 || UserIndex > OBJMAX) {
            return;
        }
        LPOBJ tmpUser = &gObj[UserIndex];
        if (tmpUser == NULL) {
            return;
        }
        ownerName.assign(tmpUser->Name);
        itemCode = ITEMGET(itemInfo->itemCategory, itemInfo->itemIndex);
        tickEnd = GetTickCount() + (itemInfo->spawnDuration * 60 * 1000);
        setSpot(UserIndex, itemInfo);
    }
    void clearSlot() {
        ownerName.assign("");
        itemCode = -1;
        tickEnd = 0;
        clearSpot();
        monsterPool.clear();
    }
    void setSpot(short UserIndex, MonsterSpawnerItemInfo* itemInfo) {
        if (UserIndex < 0 || UserIndex > OBJMAX) {
            return;
        }
        LPOBJ tmpUser = &gObj[UserIndex];
        if (tmpUser == NULL) {
            return;
        }
        for (int i = 0; i < itemInfo->spawnMonsterCount; i++) {
            int tmpMonsterIndex = gObjAddMonster(tmpUser->MapNumber);
            if (tmpMonsterIndex < 0) {
                return;
            }
            gObj[tmpMonsterIndex].m_PosNum = -1;
            gObj[tmpMonsterIndex].X    = tmpUser->X + rand() % 2;
            gObj[tmpMonsterIndex].Y    = tmpUser->Y + rand() % 2;
            gObj[tmpMonsterIndex].MapNumber    = tmpUser->MapNumber;
            gObj[tmpMonsterIndex].TX = gObj[tmpMonsterIndex].X;
            gObj[tmpMonsterIndex].TY = gObj[tmpMonsterIndex].Y;
            gObj[tmpMonsterIndex].m_OldX = gObj[tmpMonsterIndex].X;
            gObj[tmpMonsterIndex].m_OldY = gObj[tmpMonsterIndex].Y;
            gObj[tmpMonsterIndex].StartX = gObj[tmpMonsterIndex].X;
            gObj[tmpMonsterIndex].StartY = gObj[tmpMonsterIndex].Y;
            gObj[tmpMonsterIndex].m_ActState.Emotion = 1;
            gObj[tmpMonsterIndex].m_ActState.EmotionCount = 15;
            gObj[tmpMonsterIndex].Dir = rand() % 8;
            gObjSetMonster(tmpMonsterIndex, itemInfo->spawnMonsterId);
            monsterPool.push_back(tmpMonsterIndex);
        }
    }
    void clearSpot() {

        for (size_t i = 0; i < monsterPool.size(); i++) {

            gObjViewportListProtocolDestroy(&gObj[monsterPool[i]]);
            gObjViewportClose(&gObj[monsterPool[i]]);
            gObjDel(monsterPool[i]);
            gObj[monsterPool[i]].Live = 0;
            gObj[monsterPool[i]].DieRegen = 1;
        }
    }
    bool isOwner(char* OwnerName) {
        if (ownerName.compare(OwnerName) == NULL) {
            return true;
        }
        return false;
    }
    bool isMonster(short MonsterIndex) {

        for (size_t i = 0; i < monsterPool.size(); i++) {

            if (monsterPool[i] == MonsterIndex) {
                return true;
            }
        }
        return false;
    }
    bool isEmpty() {
        if (isOwner("")) {
            return true;
        }
        return false;
    }
    bool isExpired() {
        if (GetTickCount() >= tickEnd) {
            return true;
        }
        return false;
    }
    std::string ownerName;
    std::vector<short> monsterPool;
    int itemCode;
    DWORD tickEnd;
};

// monster spawner by item drop impletation
class MonsterSpawnerMng {
public:
    MonsterSpawnerMng();
    ~MonsterSpawnerMng();

    void Load();
    void Init();
    void Read(const char* File);

    void procRun();
    void procRegen(short MonsterIndex);
    bool procCreate(short UserIndex, int ItemCode);
    
    bool isPrivate(short UserIndex, short MonsterIndex);
    bool isEventMonster(short MonsterIndex);
    bool isKeyItem(int ItemCode);
    int getEmptySlot();
    MonsterSpawnerItemInfo* getItemInfo(int ItemCode);

    // singleton
    static MonsterSpawnerMng* getInstance() {
        if (m_Instance == NULL) {
            m_Instance = new MonsterSpawnerMng();
        }
        return m_Instance;
    }

private:
    static MonsterSpawnerMng* m_Instance;
    std::vector<MonsterSpawnerWorkNode> m_WorkPool;
    std::vector<MonsterSpawnerItemInfo> m_ItemData;

private:
    bool m_Loaded;
};
 
Custom Title Activated
Loyal Member
Joined
Aug 30, 2011
Messages
2,969
Reaction score
1,003
Hello guyz, in these files what about agility bug for all classes? Gen system is working fine?

Gen worked fine for me. Agility bug doesn't exist when i worked with the files.
 
Newbie Spellweaver
Joined
Mar 12, 2006
Messages
41
Reaction score
3
Hi guys, have you ever experience rage fighters loosing items in the inventory or equipped items after some couple of time?
 
Joined
Nov 29, 2009
Messages
505
Reaction score
92
Hi guys, have you ever experience rage fighters loosing items in the inventory or equipped items after some couple of time?

I did. So it was not just me. XD. But not all characters, rf only and i experienced only 1 character. Well what i did is, check the item logs for the player to know what items got lost.. Then i deleted and recreated the character again put back his lost items (actually i made him a trade :D).
 
Newbie Spellweaver
Joined
Mar 12, 2006
Messages
41
Reaction score
3
Hi guys, have you ever experience rage fighters loosing items in the inventory or equipped items after some couple of time?

Maybe someone can help to debug and fix problem? I can pay, not much becouse server dont have donate it's my hobby.
Becouse bug is very critical all my RF loosing items. If I don't fixed it I should close my server and I really dont want it :(
I noticed that in Database - Character table all RF characters loosing varbinary columns(have NULL). Quest,Inventory,Skills,MuBot etc.

If I open any RF character who loosed items IGC.EssentialTools item editor its crash.
I need to change Quest from NULL to NewCharacter. Then I can start edit with IGC.EssentialTools item editor. <- Maybe this can help.

Also when you create RF first time Quest,Skills columns = NULL <- Maybe this can help.


GameServer have no error logs.
DataServer have no error logs.
 
Newbie Spellweaver
Joined
Nov 6, 2016
Messages
42
Reaction score
14
Hi guys, i have a problem ... i can`t find in files to edit Skill DMG % from BK .. i have on full stats 6707% skill dmg and the dmg of BK,DL and RF is gigantic ... you can see what i am talking about in the print below : Thank you and please give me an answer ...
 
Custom Title Activated
Loyal Member
Joined
Apr 6, 2007
Messages
1,806
Reaction score
483
Hi guys, i have a problem ... i can`t find in files to edit Skill DMG % from BK .. i have on full stats 6707% skill dmg and the dmg of BK,DL and RF is gigantic ... you can see what i am talking about in the print below : Thank you and please give me an answer ...
You need to balance skills, via LUA scripting, reformulate them to give "lower dmg".....its not an easy task tho.

 
Junior Spellweaver
Joined
May 11, 2008
Messages
105
Reaction score
9
after multiple tries, changing IGC.DLLs, trying different CSs, disabling DLL check on login (allow login invalid dll = 1)
I still cannot login to a server that's hosted on LAN with all LAN IPs configured.
I get immediate DC after main.exe loads.
Dummy 1.02Q server setup locally works fine.
I don't know what to do anymore

What I tried:
Ashlay's EXEs
Ashlay's DLL
Stock EXEs
Stock DLLs
Repacked Bins
HEX Edit of Main and IGC.Dll
enabling loopback
gameserver.ini (disable DLL Check or smtg along those lines)

FILES USED:
Everything that was provided in this thread
Originals (with AUTH system disabled)
and ASHLAY modified files

EDIT:
hosted on
server 2012 R2 x64
SQL 2012 Enterprise
 
Last edited:
Joined
Nov 29, 2009
Messages
505
Reaction score
92
after multiple tries, changing IGC.DLLs, trying different CSs, disabling DLL check on login (allow login invalid dll = 1)
I still cannot login to a server that's hosted on LAN with all LAN IPs configured.
I get immediate DC after main.exe loads.
Dummy 1.02Q server setup locally works fine.
I don't know what to do anymore

What I tried:
Ashlay's EXEs
Ashlay's DLL
Stock EXEs
Stock DLLs
Repacked Bins
HEX Edit of Main and IGC.Dll
enabling loopback
gameserver.ini (disable DLL Check or smtg along those lines)

FILES USED:
Everything that was provided in this thread
Originals (with AUTH system disabled)
and ASHLAY modified files

EDIT:
hosted on
server 2012 R2 x64
SQL 2012 Enterprise

what is your ip, i'll make you igc dll.
 
Last edited by a moderator:
Skilled Illusionist
Joined
Jun 22, 2017
Messages
363
Reaction score
557
after multiple tries, changing IGC.DLLs, trying different CSs, disabling DLL check on login (allow login invalid dll = 1)
I still cannot login to a server that's hosted on LAN with all LAN IPs configured.
I get immediate DC after main.exe loads.
Dummy 1.02Q server setup locally works fine.
I don't know what to do anymore

What I tried:
Ashlay's EXEs
Ashlay's DLL
Stock EXEs
Stock DLLs
Repacked Bins
HEX Edit of Main and IGC.Dll
enabling loopback
gameserver.ini (disable DLL Check or smtg along those lines)

FILES USED:
Everything that was provided in this thread
Originals (with AUTH system disabled)
and ASHLAY modified files

EDIT:
hosted on
server 2012 R2 x64
SQL 2012 Enterprise

ServerInfo.cpp
Code:
void CServerInfo::Load(std::string file)
{
	char ver[5];
	char szTemp[250];
	LPSTR filedec = "/ServerInfo.bmd";

	FILE* hFile = fopen(file.c_str(), "rb");
	if (!hFile)
	{
  MessageBoxA(0, "ServerInfo.bmd is missing", "ERROR", 0);
  ExitProcess(0);
	}

	fseek(hFile, 0, SEEK_END);
	int size = ftell(hFile);
	fseek(hFile, 0, SEEK_SET);

	BYTE* buf = new BYTE[size];
	fread(buf, 1, size, hFile);
	fclose(hFile);

	for (int i = 0; i < size; i++)
	{
  buf[i] ^= xorKey[i % 4];
	}

	std::ofstream decFile;
	decFile.open(filedec);
	decFile << buf;
	decFile.close();

	GetPrivateProfileStringA("Connection", "IP", "10.0.0.1", szTemp, 250, filedec);
	m_Ip = std::string(szTemp);
	m_Port = GetPrivateProfileInt("Connection", "Port", 44405, filedec);
	m_ChatServerPort = GetPrivateProfileIntA("Connection","ChatPort", 56960, filedec);
	GetPrivateProfileStringA("Main", "Version", "1.05.25", szTemp, 8, filedec);
	sscanf(szTemp, "%c.%c%c.%c%c", &ver[0], &ver[1], &ver[2], &ver[3], &ver[4]);
	for (int i = 0; i < 5; i++)
	{
  ver[i] = ver[i] + (i + 1);
	}
	memcpy(m_Version, ver, 5);

	GetPrivateProfileStringA("Main", "Serial", "PoweredByIGCN800", szTemp, 17, filedec);
	memcpy(m_Serial, szTemp, 16);
	m_UseLauncher = GetPrivateProfileIntA("Launcher", "Enabled", 0, filedec);
	GetPrivateProfileStringA("Launcher", "ExeName", "Launcher.exe", szTemp, 255, filedec);
	m_LauncherFile = std::string(szTemp);
	m_AllowXShop = GetPrivateProfileIntA("Gameplay", "SellXShopQuestItems", 0, filedec);
	m_Charset = GetPrivateProfileIntA("Gameplay", "CodePage", 0xFDE9, filedec);/** 1258vn0x4B0 0x4E4 */
	m_BlockVirtualMachine = GetPrivateProfileInt("Gameplay", "BlockVirtualMachine", 0, filedec);
	m_UsePatcher = GetPrivateProfileIntA("Patcher", "Enabled", 0, filedec);
	GetPrivateProfileStringA("Patcher", "ExeName", "Patcher.exe", szTemp, 255, filedec);
	m_PathcherFile = std::string(szTemp);
	
	DeleteFileA(filedec);
}

and change IP in ServerInfo.bmd
 
Newbie Spellweaver
Joined
Jan 29, 2015
Messages
12
Reaction score
2
Does anyone notice DW cannot attack player (or monster) while in teleport. In SS6 or SS8, it works normally
 
Newbie Spellweaver
Joined
Nov 6, 2016
Messages
42
Reaction score
14
Does anyone notice DW cannot attack player (or monster) while in teleport. In SS6 or SS8, it works normally
I wonder if that is a problem from the client or from the server ,if it is from the client then nobody will fix that.
 
Custom Title Activated
Loyal Member
Joined
Apr 6, 2007
Messages
1,806
Reaction score
483
I wonder if that is a problem from the client or from the server ,if it is from the client then nobody will fix that.
at data/skills/IGC_SKILLSETTINGS.ini:

[SkillInfo];---------------------------------------------------------------------;-- Determines whether Dark Wizard can use skills during teleport, 0/1;---------------------------------------------------------------------CanDarkWizardUseSkillsWhileTeleport = 0
 
Newbie Spellweaver
Joined
Mar 20, 2010
Messages
11
Reaction score
0
Someone can tell me how to make other ppl connect to server? Mapserverinfo and server list set to ipv4, serverinfo set to wan ip but client freeze when someone try to connect. only local connection is work, all neccessary ports are open
 
Newbie Spellweaver
Joined
Nov 6, 2016
Messages
42
Reaction score
14
Does anyone have problem with crash on GS when Lord Silvester is atacked ?!

Any idea or guidance on why a gameserver will crash without a dmp sometimes ? I have enough space.
 
Last edited:
Joined
Aug 6, 2005
Messages
550
Reaction score
296
@drakelv: is the included PacketTwister algorithm the complete "official" one, or not?
I tried to encrypt(twist) a chat packet and compared it to a 'twisted' one which I captured a few years ago with ex700 GMO, but the result wasn't the same which has been sent to the server back then.
 
IGCN Co-Founder
Joined
Jun 26, 2006
Messages
303
Reaction score
487
@drakelv: is the included PacketTwister algorithm the complete "official" one, or not?
I tried to encrypt(twist) a chat packet and compared it to a 'twisted' one which I captured a few years ago with ex700 GMO, but the result wasn't the same which has been sent to the server back then.

No it's old, you have to reverse it from main.exe.
 
Back
Top