View previous topic :: View next topic |
Author |
Message |
FunkySwerve
Joined: 02 Jun 2005 Posts: 377
|
Posted: Thu Aug 04, 2005 1:49 Post subject: Switching from Windows to Linux - Help! |
|
|
Ok, I'm in the process of moving my mod from a Win XP system to a professional host's Linux box. My mod uses the newest NWNX, MySQL, and nwnx_leto 23 beta 5. They installed some Linux package of NWNX(unsure if it was the most current zip from the downloads or not). I u/l'd my windows version of aps_demo mod (most recent windows version), both to test it out and to add a persistant object table to the mysql database, since his aps_demo.mod had not done so. On the first attempt, the persistant variable didn't look like it retrieved correctly( "persistant variable retrieved:" was all of the message), and the chest, instead of creating one each of the 3 items, created 25 pagefuls of the first item. Now, I am highly unfamiliar with Linux, but this seems like the sort of problem I had with my Windows install, untill I figured out the correct settings in the ini file etc. I then read the install notes in the most recent nwnx - linux release, and noticed the blurb about adding code to the modules load script. So I inserted the code:
Code: |
object oTgt=GetModule();
SetLocalString(oTgt,"NWNX!INIT","1");
|
and tried again, with identical results. I could just about fill the Grand Canyon with all the things I don't know here, so I'll ask 4 questions to start (some of these are no doubt silly but I'll chalk that up to complete inexperience with Linux):
1) Whats the fastest way to check the version of nwnx for linux the professional host installed? Which logfile has the version #? And what is the most current version? What about checking the type of linux the host is using? Does that even matter?
2) Is there any reason I would need the most current version? I assume I will since thats what I'm running on Windows but have no real idea. Aside from profiler, I am using both persistant ints and objects, and am running nwnx_leto 23 beta 5.
3) What are the names of the linux logfiles you need to see to help me figure out what's going on here?
4) Assuming the host DID install the correct (most recent) version of NWNX, and did that setup correctly, what do I need to do to my mod to get it compatible? Is the only necessary change the onload insertion, or are there other changes to be made as well?
Just to clarify, the host ran an older version of aps_demo.mod on the server before I ever accessed it (presumably the one that came with his linux nwnx zip), and said that the mysql table was successfuly created when he checked it. NWNX does correctly startup the module (or the .sh script he gave me that uses it does, anyhow).
Thanks you in advance for any assistance you can offer.
FunkySwerve |
|
Back to top |
|
|
FunkySwerve
Joined: 02 Jun 2005 Posts: 377
|
Posted: Thu Aug 04, 2005 3:37 Post subject: |
|
|
Oh, one last question, just in case: Can the Linux version of NWNX support persistant object storaage (as opposed to persistant int/string storage)? I only ask because if not, I'm sorta in between a rock and a hard place.
Funky |
|
Back to top |
|
|
Papillon x-man
Joined: 28 Dec 2004 Posts: 1060 Location: Germany
|
Posted: Thu Aug 04, 2005 8:34 Post subject: |
|
|
I have to pass those questions to someone currently using Linux and NWNX - too much time has passed and I can not remember exactly how to go about debugging connectivity problems on Linux.
The question about nwnx-linux and object storage I can answer: The Linux version has no support for persistent objects. Some people started work on it, but so far no working version exists. _________________ Papillon |
|
Back to top |
|
|
FunkySwerve
Joined: 02 Jun 2005 Posts: 377
|
Posted: Fri Aug 05, 2005 10:36 Post subject: |
|
|
That's what I was afraid of. Ok, so now I have a huge db full of persistant objects associated with characters. I can convert the vault to use persistant strings instead of objects (create object using resefs), but how the heck am I gonna make the change in sql, and asociate them with the respective players? Or is it as easy as converting the objects to strings? Do the stored objects have resref strings that I could access? Has anyone encountered this dilemma before and found a way to deal with it? Is there some script I could write and run in a mod that would do the conversion? Im afraid my grasp of how the persistant functions work is a bit weak here. Is there any marker made on the character at all or does a persistant objects exist as no more than a db entry with the characters name etc? Any help would be most welcome, I'm in a real bind here.
Sincerely,
Funky |
|
Back to top |
|
|
Papillon x-man
Joined: 28 Dec 2004 Posts: 1060 Location: Germany
|
Posted: Sat Aug 06, 2005 9:29 Post subject: |
|
|
Well, I recently converted the persistent chests of Avlis to use object storage. In order to do that, I created a dummy module that contained all items of all Avlis servers and a script that read resref by resref of the old chest table, created the corresponding object, and wrote the binary data into a new table.
Of course, this is the other way round, but I see no reason why it should not work in the other direction. _________________ Papillon |
|
Back to top |
|
|
FunkySwerve
Joined: 02 Jun 2005 Posts: 377
|
Posted: Sat Aug 06, 2005 19:20 Post subject: |
|
|
Mind sharing that script? Would save a heap of time I guessing.
Thanks,
Funky |
|
Back to top |
|
|
teleri
Joined: 28 Jan 2005 Posts: 21
|
Posted: Sat Aug 06, 2005 23:58 Post subject: |
|
|
the easiest way to see which version of NWN you have installed is to try connecting with a version that is not current. a version 1.33 client etc... The log file doesn't show the version installed. you can also as a DM call the version via a command which I can not remember ATM.
Yes you want the most current/the version you were on before. it is important as it will limit your player base.
the log files are in /<path to NWN>/nwn/logs.0/
for the compatability issue Papillon is your best bet |
|
Back to top |
|
|
FunkySwerve
Joined: 02 Jun 2005 Posts: 377
|
Posted: Sun Aug 07, 2005 6:18 Post subject: |
|
|
teleri wrote: | the easiest way to see which version of NWN you have installed is to try connecting with a version that is not current. a version 1.33 client etc... The log file doesn't show the version installed. you can also as a DM call the version via a command which I can not remember ATM.
Yes you want the most current/the version you were on before. it is important as it will limit your player base.
|
Thank you Captain Obvious! I generally don't huck rotten eggs at people trying to help me, but...really. Assuming I was that clueless was pretty silly, given the somewhat advanced nature of the topic, and on top of that you had to misread the question AND completely disregard the fact that these are the nwnX forums. Roofles. Anyway, I do appreciate the path, but that wasn't what I was asking for either. I was asking which logs were needed to help troubleshoot, but that's a moot point, since Pap already made clear the problem - the Linux version of nwnX (note the 'X') doesn't support persistent objects. In any case, thank you for trying to help.
Best,
Funky |
|
Back to top |
|
|
Papillon x-man
Joined: 28 Dec 2004 Posts: 1060 Location: Germany
|
Posted: Sun Aug 07, 2005 10:05 Post subject: |
|
|
Well, the script is nothing special. I guess you get the general idea by looking at it, you just need to reverse the process since you are going in the opposite direction. The idea is to load one line at a time, create the item on the first player (make sure you are the only one in the module), then write it to the new table (addItem), then destroy it and continue with the next. The whole process took about 1.5 hours for Avlis' 100K items.
Code: |
// Name : convertpchest.nss
// Purpose : Convert from old to new pchests
// Author : Papillon
// Modified : July 2, 2005
#include "aps_include"
#include "pconvert_add"
void convert(string sContainerFilter)
{
string sSQL;
int bSQLSuccess;
object oModule = GetModule();
object oDummyPlayer = GetFirstPC();
object oDummyContainer = GetObjectByTag("dummycontainer");
object oItem;
int iCount;
string sContainer;
string sItem;
string sCount;
string sId;
do
{
sSQL = "SELECT container,item,count,identified FROM containers ";
if (sContainerFilter != "")
sSQL = sSQL + "WHERE container='" + sContainerFilter + "' ";
sSQL = sSQL + "LIMIT 1";
SQLExecDirect(sSQL);
bSQLSuccess = SQLFetch();
if (bSQLSuccess == SQL_SUCCESS)
{
sContainer = SQLGetData(1);
sItem = SQLGetData(2);
sCount = SQLGetData(3);
sId = SQLGetData(4);
// create item and add to new chest...
iCount++;
if (sItem == "NW_IT_GOLD001")
oItem = CreateItemOnObject(sItem, oDummyContainer, 1);
else
oItem = CreateItemOnObject(sItem, oDummyPlayer, 1);
if (GetIsObjectValid(oItem))
{
SetIdentified(oItem, StringToInt(sId));
addItem(sContainer, oItem, sCount);
}
else
{
// not found in palette....
sSQL = "INSERT INTO xcontainers (container, item, count, identified) VALUES " +
"('" + sContainer + "'," +
"'" + sItem + "'," +
"'" + sCount + "'," +
"'" + sId + "')";
SQLExecDirect(sSQL);
}
// delete from old chest....
sSQL = "DELETE from containers WHERE " +
"container = '" + sContainer + "' AND " +
"item = '" + sItem + "' AND " +
"count = '" + sCount + "' AND " +
"identified = '" + sId + "'";
SQLExecDirect(sSQL);
DestroyObject(oItem);
}
}
while (iCount < 50 && bSQLSuccess);
if (bSQLSuccess)
DelayCommand(0.1f, convert(sContainerFilter));
}
void main()
{
convert("MidnightsChest1");
// convert("");
}
|
Note: an empty container filter means that all chests will be converted. _________________ Papillon |
|
Back to top |
|
|
FunkySwerve
Joined: 02 Jun 2005 Posts: 377
|
Posted: Mon Aug 15, 2005 18:29 Post subject: |
|
|
I've struggled with this off and on for the last week, with no success. The first problem is that I dont understand the looping functionality you use (though I'm familiar with do/while, the SQLFetch command is a mystery, as is why the functions it replaced were replaced), and the second is that I dont understand how GetPersistantObject goes from MySQL to inventory item. My system stores the objects 'on' each character. I want to switch to an identical saystem, only one that stores strings instead of objects, and retrieves thoses strings to do a create object. Not the least laggy way to do things but the simplest, and my time is at a premium at the moment. The framework for what I want to do is this:
get first object (row) in db pwobjdata (identical setup to default pwobjdata table)
create that object
get the string of that object
if the string is vaild, store it in db objdata (setup identical to default pwdata table) on the same character
This means that most of the vaules are identical, I just need to go from object data to string, creating the data in a new db as I go so I can delete the old db when finished.
I see how you pulled data from your sql data using SQLGetData1 etc, and setting those data equal to the strings, but Im not sure whether I would do the same for an object, setting and SQLGetData call equal to an object - that doesn't make sense I don't think, especially when I look at the fact that GetPersistantObject uses a RetrieveCampaignObject call. I cannot fathom, however, how to do this conversion.
With the loop, it's just not clear to me what should be different when I need to loop through every row in the db. I can't be sure, but I dont think just leaving the string sContainerFilter as an empty string like you have commented out would do the trick.
In any case, I'm pretty lost, as you no doubt can tell - my grasp of MySQL is just too weak. Any guidance you can give would be, as always, greatly aprecciated, both by me nd my players (who have been running around bankless and intless as I attempt this conversion!).
Sincerely,
FunkySwerve |
|
Back to top |
|
|
Papillon x-man
Joined: 28 Dec 2004 Posts: 1060 Location: Germany
|
Posted: Tue Aug 16, 2005 11:08 Post subject: |
|
|
Well, keep in mind that I was converting from strings to objects, while you want to convert from objects to strings, exactly the other way round.
You can use the script above as a framework to do your own conversion, especially the way I loop through the entire table, processing one row at a time. It is not something you can just drop into your module without modification. Does that answer your question ? _________________ Papillon |
|
Back to top |
|
|
FunkySwerve
Joined: 02 Jun 2005 Posts: 377
|
Posted: Tue Aug 16, 2005 19:49 Post subject: |
|
|
Not even remotely. A large part of the problem is that I was using my own crude storage system, without having seen a more refined system at work. I'm looking at the system from the Vault mentioned in the scripts/mods thread and its clearing a few things up, however, since it has another examle of a loop.
Funky |
|
Back to top |
|
|
teleri
Joined: 28 Jan 2005 Posts: 21
|
Posted: Wed Aug 17, 2005 19:10 Post subject: |
|
|
FunkySwerve wrote: | teleri wrote: | the easiest way to see which version of NWN you have installed is to try connecting with a version that is not current. a version 1.33 client etc... The log file doesn't show the version installed. you can also as a DM call the version via a command which I can not remember ATM.
Yes you want the most current/the version you were on before. it is important as it will limit your player base.
|
Thank you Captain Obvious! I generally don't huck rotten eggs at people trying to help me, but...really. Assuming I was that clueless was pretty silly, given the somewhat advanced nature of the topic, and on top of that you had to misread the question AND completely disregard the fact that these are the nwnX forums. Roofles. Anyway, I do appreciate the path, but that wasn't what I was asking for either. I was asking which logs were needed to help troubleshoot, but that's a moot point, since Pap already made clear the problem - the Linux version of nwnX (note the 'X') doesn't support persistent objects. In any case, thank you for trying to help.
Best,
Funky |
--==Edited==-- I wrote a pretty evil reply but as the case my be I could care less. Good luck and I hope you get it working. |
|
Back to top |
|
|
FunkySwerve
Joined: 02 Jun 2005 Posts: 377
|
Posted: Thu Aug 18, 2005 0:54 Post subject: |
|
|
Ok, here's what I was able to cook up. I let it run for an hour and a half, and finally stopped it since I figured something muyst've gone wrong. When I checked the objdata db, here's a small sample of what I got:
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:40 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:40 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:40 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:40 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:40 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:40 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:40 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:40 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:40 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:40 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:40 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:40 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:40 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:40 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:40 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:40 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:41 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:41 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:41 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:41 |
| ~ | Chest1 | Item_0 | | 0 | 2005-08-17 13:47:41 |
+--------+--------+--------+------+--------+---------------------+
Here's the script I used, if it can be called that:
Code: |
// Name : convertpchest.nss
// Purpose : Convert from old to new pchests
// Author : Papillon
// Modified : July 2, 2005
#include "aps_include"
void convert(string sContainerFilter)
{
string sSQL;
int bSQLSuccess;
object oModule = GetModule();
object oDummyPlayer = GetFirstPC();
object oItem;
int iCount;
string sPlayer;
string sTag;
string sName;
string sVal;
string sResRef;
do
{
sSQL = "SELECT player,tag,name,val FROM pwobjdata ";
sSQL = sSQL + "LIMIT 1";
SQLExecDirect(sSQL);
bSQLSuccess = SQLFetch();
if (bSQLSuccess == SQL_SUCCESS)
{
sPlayer = SQLGetData(1); //SQLEncodeSpecialChars(GetPCPlayerName(oOwner)) if PC, "~" otherwise
sTag = SQLGetData(2); //SQLEncodeSpecialChars(GetName(oOwner)) if PC, GetTag(oOwner) otherwise
sName = SQLGetData(3); //sVarName "STORAGE"+sKey+sCount
sVal = SQLGetData(4); //the object blob
// create item and add to new chest...
iCount++;
SetLocalString(GetModule(), "NWNX!ODBC!SETSCORCOSQL", sVal);
//if (sItem == "NW_IT_GOLD001")
// oItem = CreateItemOnObject(sItem, oDummyContainer, 1);
//else
// oItem = CreateItemOnObject(sItem, oDummyPlayer, 1);
oItem = RetrieveCampaignObject ("NWNX", "-", GetLocation(oDummyPlayer), oDummyPlayer);
sResRef = GetResRef(oItem);
sResRef = SQLEncodeSpecialChars(sResRef);
/*
if (GetIsObjectValid(oItem))
{
SetIdentified(oItem, StringToInt(sId));
addItem(sContainer, oItem, sCount);
}
else
{
// not found in palette....
sSQL = "INSERT INTO xcontainers (player, tag, name, val) VALUES " +
"('" + sContainer + "'," +
"'" + sItem + "'," +
"'" + sCount + "'," +
"'" + sId + "')";
SQLExecDirect(sSQL);
}
*/
//insert into new chest -
sSQL = "INSERT INTO objdata (player, tag, name, val, expire) VALUES " +
"('" + sPlayer + "'," +
"'" + sTag + "'," +
"'" + sName + "'," +
"'" + sResRef + "'," +
"'" + "0" + "')"; //left extra quotes because paranoid
SQLExecDirect(sSQL);
// delete from old chest....
sSQL = "DELETE from pwobjdata WHERE " +
"player = '" + sPlayer + "' AND " +
"tag = '" + sTag + "' AND " +
"name = '" + sName + "' AND " +
"val = '" + sVal + "'";
SQLExecDirect(sSQL);
DestroyObject(oItem);
}
}
while (iCount < 30 && bSQLSuccess);
if (bSQLSuccess)
{
DelayCommand(0.1f, convert(sContainerFilter));
}
else
{
FloatingTextStringOnCreature("Conversion complete.", oDummyPlayer);
}
}
void main()
{
// convert("MidnightsChest1");
convert("");
}
|
Hopefuly this makes clear the nature of my confusion. Do I need to redeclare
sSQL = "SELECT player,tag,name,val FROM pwobjdata ";
sSQL = sSQL + "LIMIT 1";
SQLExecDirect(sSQL);
somewhere? As always, ant help is most appreciated.
Many thanks,
Funky |
|
Back to top |
|
|
Papillon x-man
Joined: 28 Dec 2004 Posts: 1060 Location: Germany
|
Posted: Fri Aug 19, 2005 8:31 Post subject: |
|
|
some quick comments:
sVal = SQLGetData(4); //the object blob
-> will always fail, remove that
"val = '" + sVal + "'";
-> also remove that part from the final delete statement
The script ran endlessly because the delete statement always fails. Check the log file when doing things like this, you will likely see what's going wrong there.
Otherwise, the script looks good. _________________ Papillon |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|