IslandzVW / halcyon

InWorldz Halcyon 3d virtual reality world simulator
BSD 3-Clause "New" or "Revised" License
21 stars 26 forks source link

Initial Grid Setup: Going Public #298

Closed sonjamichelle closed 7 years ago

sonjamichelle commented 7 years ago

After hashing out most of the major issues I've got a pretty stable 20 region grid up and running. Though it's kinda lonely on there with just the two of us. We'd like to open the grid to others, right now the only way to create users is to manually do via the user console. I can't be at the console all the time. How do I setup a way to automate the user creation process for someone visiting the grid website?

Another thing I've tried to Implement is buying land, for right now at $0, using landtool.php. Though I failed miserably. I think it was because I tried using the landtool.php from the OpenSim wiki. Eventually I would like to implement an economy as well. Basic at first. Baby steps.

Main priority is user creation. I want to be able to invite others to the grid without having to manually create the accounts.

Vinhold commented 7 years ago

As one who has been there, done that, I have some advice. The php pages are mostly junk. If you know programming and can write your own website using .Net or whatever server side programming you like, you have a fighting chance. I have a core website in .Net VB started as a beginning point for a new grid, Just have not had a chance yet to post it someplace as an option. It handles new accounts, avatar selection (if you have some created) and how to transfer the avatar elements / clothing / accessories so the new account will arrive ready to go as expected. One good bit of news for the future is that a service is being developed that will provide an API tool kit in Halcyon for websites to handle all the tasks of new accounts, and other data not so easy to access that supports website actions for a grid. The land tool in PHP is an even worse disaster and I have found its code to be very misleading. Only one of the two parts it has is called, the other is never called. I rewrote it in .Net and finally got it working after figuring out what the viewer actually sent to the page. I also had to put in an IIS page redirect from landtool.php to my actual page since the page name is hard coded in the viewer for some reason. Check my profile for my website, use the contact us page, I would be happy to send you the website source code or the MySQL commands for the data transfers to set up accounts. Processes in it can easily be converted to any other .Net language as desired. At least until I can set up the website pages in Github for access. The whole process for website support is going to be changing while the API system gets created.

sonjamichelle commented 7 years ago

I'm certainly not a programmer. I mostly hack and slash my way through. Any assistance you can provide would be greatly appreciated. I would definitely like to take a look at what you have. See if I can set something up of my own. Email would be sonja (at) iwz-designcreations.com

sonjamichelle commented 7 years ago

Inspired by the information that @Vinhold sent me, I was able to create a simple Create An Avatar Account Page. I was then able to create a simple splash page for the viewer using Oni Kenkon's github code as a basis. (http://www.moonlight-grid.com/splash) I'm working on some simple management pages, I am able to create a login page that authenticates a user based on the grid database. From there I haven't decided what to do yet. Though my next step could be a simple events creation page. A user authenticates then can create an event. I see the events table in the database. What I need is the information that populates the table. Such as, what are the categories? Eventflags? What format is the eventid, simple integer or something else? And what format globalposition needs to be in. The rest of the columns are pretty self explanatory. Then I just have to figure out how to convert the time suppled to unix time stamp, and the duration to seconds. I'm sure I can find that stuff easily enough on the net. I found uuid() for mySQL for the user account creation ;-)

Plugging along slowly but surely.

appurist commented 7 years ago

The event categories are in theory flexible but I think we chose to just go with the default values in the viewer (flexibility not implemented). They are optionally sent back on a LoginResponse but I think we don't ever send any (if I recall correctly). Or we match the SL ones. Event flags are the just maturity ratings, I think. General=0, Mature=1, Adult=2. I had found a list of event categories somewhere in the distant past, but I can't seem to find them now.

appurist commented 7 years ago

Splash page looks good! I forgot to mention that the event ID was just an auto-increment database column at IW and the code references it as a uint32. Global pos is a location anywhere on the map, so it's coordinates of the region * 256. So something like 256005,256010,22 is in region (1000,1000) at 5/10/22.

appurist commented 7 years ago

The list of category types is at https://github.com/InWorldz/halcyon/blob/master/OpenSim/Region/CoreModules/Avatar/Search/AvatarSearchModule.cs#L980 and for convenience:

if (row["category"] == "18")
    data.category = "Discussion";
if (row["category"] == "19")
    data.category = "Sports";
if (row["category"] == "20")
    data.category = "Live Music";
if (row["category"] == "22")
    data.category = "Commercial";
if (row["category"] == "23")
    data.category = "Nightlife/Entertainment";
if (row["category"] == "24")
    data.category = "Games/Contests";
if (row["category"] == "25")
    data.category = "Pageants";
if (row["category"] == "26")
    data.category = "Education";
if (row["category"] == "27")
    data.category = "Arts and Culture";
if (row["category"] == "28")
    data.category = "Charity/Support Groups";
if (row["category"] == "29")
    data.category = "Miscellaneous";
sonjamichelle commented 7 years ago

So what would the global position be for the co-ords of a region at 999,998 61,63,22. I tried following your example, but it keeps putting me at 1000,1000.

appurist commented 7 years ago

Should be 999*256+61, 998*256+63, 22.

sonjamichelle commented 7 years ago

I must be dense. Because I'm not getting it to work. Enter what you gave me gives me an invalid location (0,0,0). Entering 999319,998317,22 gives me co-ords that are off and results in an invalid location as well. It's been a long night. I'm working on several things at once and learning new tricks at the same time. So forgive me if I'm missing the obvious. ;-)

kf6kjg commented 7 years ago
GlobalCoord=RegionCoord*256+LocationCoord

So for a region at <999, 888>, multiply that by 256 then add the location vector.

sonjamichelle commented 7 years ago

Somehow, for some reason that just clicked and it worked. I think I have it now. Once I'm done with this password reset code, I can work on an event page.

appurist commented 7 years ago

I think since my first example used 1000,1000 as the region coordinates, it seemed to make sense that this was the factor to multiply and so you were multiplying by 1000 at first (instead of 256). The usual default location for the center of a new grid is 1000,1000 so that's why I chose that as sample region coordinates, but it may have been better to use values slightly less to keep them from standing out as something more special than just region coordinates. But glad you got it sorted out. Good luck with the event page!

sonjamichelle commented 7 years ago

Ok, I've FINALLY got a working Password Reset page going, however it doesn't quite work properly. It changes the password in the database but the user can't log on. I'm assuming it's because I'm getting the hash or the crypt wrong. What does halcyon use?

Vinhold commented 7 years ago

Here is what you need: ' Password processing formula: md5(md5("password") + ":" + passwordSalt) ' MD5 Reference: http://www.aspnettutorials.com/tutorials/advanced/md5-secret-aspnet2-vb/ ' OpenSim Docs: http://opensimulator.org/wiki/AuthIntegration Dim pass() As Byte = Encoding.UTF8.GetBytes(strChange) Dim md5 As MD5 = New MD5CryptoServiceProvider() Dim strPassword As String = Encoding.UTF8.GetString(md5.ComputeHash(pass)) Please note that the salt value must be an empty string! The internals of the Halcyon system has not all cases of the password / salt implemented so the current solution is to have it an empty string. This information should help you debug your process. Code is .Net VB, but should be convertible to any other .Net language. The OpenSim link shows their implementation code.

Vinhold commented 7 years ago

In fact here is the function I created to have one place to handle the process: ' Encodes the password hash for user accounts. Public Function CodePassword(ByVal strPassword As String, ByVal strSalt As String) As String Dim PasswordHash As String PasswordHash = ""

Dim bPass(), hPass(), bSalt() As Byte bPass = Encoding.UTF8.GetBytes(strPassword) Dim MD5 As New System.Security.Cryptography.MD5CryptoServiceProvider hPass = MD5.ComputeHash(bPass) bSalt = Encoding.UTF8.GetBytes(BitConverter.ToString(hPass).Replace("-", "").ToString().ToLower() + ":" + strSalt.ToString()) PasswordHash = BitConverter.ToString(MD5.ComputeHash(bSalt)).Replace("-", "").ToString().ToLower()

Return PasswordHash.ToString() End Function

kf6kjg commented 7 years ago

Vin was running under my misread of the source when he said "Please note that the salt value must be an empty string!" - I've just completed a re-review of the source and I was mistaken: all places that READ and VERIFY a password use the salt correctly, so PLEASE DO use a good salt of exactly 32 bytes.

What it wasn't doing was creating salts for internally created new accounts and internally fired password resets. I've just submitted #299 to correct that.

sonjamichelle commented 7 years ago

Ok, still not getting it to work.

Here's what I have:

`if(isset($_POST['submit'])) { $new_password = $_POST['new_password']; $retype_password = $_POST['retype_password'];

if($new_password == $retype_password)
{
    $salt = '9930daf3eb914a41be38-26879454e3a9';
    $hash = md5($salt . $retype_password);
    $update_password = mysqli_query($db, "UPDATE users SET passwordHash = '$hash' WHERE UUID = '$userID'");
    if($update_password)
    {
            mysqli_query($db, "UPDATE recovery_keys SET valid = 0 WHERE userID = '$userID' AND token ='$token'");
            $msg = 'Your password has changed successfully. Please login with your new passowrd.';
            $msgclass = 'bg-success';
    }
}else
{
     $msg = "Password doesn't match";
     $msgclass = 'bg-danger';
}

} `

It's changing the password in the DB, but it's not letting me log in and it's not setting the right value. For instance I have a couple of users using the same password, so their hashes are the same. (I know, not safe shoot me later) If I set the password the same as those it should match. but it doesn't.

Vinhold commented 7 years ago

Note the formula: md5(md5("password") + ":" + passwordSalt) You have in your code: $hash = md5($salt . $retype_password); It is not the same as the formula requires. I am not familiar with the language you are using, but my guess would be you need something like $hash = md5(md5($retype_password).":".$salt ); and your DB needs "UPDATE users SET passwordHash = '$hash', passwordSalt = '$salt' WHERE UUID = '$userID'" as the salt has to be stored with the passwordHash. The principle here is that if a salt is used, it is a randomly generated string each time it is called, so to have it checked again later, the salt must be stored in the table with the hash.

sonjamichelle commented 7 years ago

AHAA! Login success! Thanks. Now for security I want to generate a random salt as you suggested for each user. gotta research that. But at least we're cooking with gas now! ;-)

sonjamichelle commented 7 years ago

Now where cookin'! I realized I already had a function to create a random token. So I just copied it and modified it to create me a 32byte random salt. ;-)

sonjamichelle commented 7 years ago

I have a rudimentary login in system, created an avatar page,a password reset page and getting ready to work on an events page. One of the pages currently lists my regions for lack of anything else to display. Where in the database do I find where an region is online or offline? Or do I have to query the server and if so how would I do that?

appurist commented 7 years ago

Actually the regions table should only be showing regions that are up. There isn't really a concept of an offline region (it just doesn't exist) unless you have a separate table of regions for management purposes (e.g. InWorldz has one for billing the owners).

sonjamichelle commented 7 years ago

Yup, sure 'nuff. I brought down one of my Waters regions and it disappeared from the regions table. Now to make use of it. ;-)

sonjamichelle commented 7 years ago

Here's a thought, I could set up a cron job that queries the regions table every so often. it then compares that list against a list of known regions then sets a flag in a management table to online/offline, last seen online, etc where a page can query that management table and pull the stats.

Am I way off the mark? Reinventing the wheel? Off my rocker? In need of a straight-Jacket?

appurist commented 7 years ago

It depends on your goal. If you want to report something like nn of nn regions online, I think if you have the regions table, and a table like known_regions (or even a config file, or even just an expected count somewhere), you can just compare COUNT(*) FROM regions to the expected count and report that. But if you just want to report how many regions are up and whether the grid is online, you can just grab that COUNT(*) and report it and check it for 0 to determine if the grid is down. (It all depends on what you want to consider "down". That's one way to determine down.)

sonjamichelle commented 7 years ago

Well, as you can see on my splash page I have a region count. It shows the number of regions running. Take one down pass it around and I have one less in the count. What I'm kind of hoping to do, since we're small enough, is to list the running regions in a table and put online/offline next to it. I know it would be a daunting task if we ever grew but right now it seems like a simple task to accomplish being that we're a tiny community. ;-)

appurist commented 7 years ago

Ah yes then you'll need to have a list of known or expected regions. To be honest, I'd go the route of just having another table in your database. That way the known and online regions are pretty much the same source, and an offline region is just one that is in the known table but not the online regions table.

sonjamichelle commented 7 years ago

I hope I'm not driving y'all crazy yet. ;-)

I've got a working query to pull events out of the database and I've prettied up the fields like dateUTC and Categories (Thanks @appurist for the info it helped considerably!). Now I need to make globalPos human readable again. Yeah I know, after all the trouble of converting it in the DB in the first place. Straight math doesn't quite work, gives me a decimal number. For instance 255834 comes up 999.21875. I've got the Sim co-ords but I don't have the parcel co-ords.

Other than that, things are progressing smoothly. Here's the data pulled from the events table. http://www.moonlight-grid.com/vartest.php Now to just make it shiny.

appurist commented 7 years ago

For the global to local coordinates, the just take the modulo of the global coordinate (the remainder after dividing by 256).

So the X coordinate for the regionX = globalX % 256 and the local offset within that region localX = globalX / 256 so 255834 would be region at 999, with an X coordinate in the region of 255834 % 256 or 90. (See the PHP modulo "mod" operator here. Although you might want to use regionX=intdiv(globalX,256) instead to force an integer to be returned.)

Or simpler numbers, global X coordinate of 522 would be map X coordinate 2, with an X value in the region of 10.

appurist commented 7 years ago

Another thing worth noting, since you may want to convert region coordinates / global location to a region name.

In the regions table, there are locX and loxY fields for the map coordinates of the region. But if they are also combined into the regionHandle field.

For example, my second test region is at 1001,1000 and has a regionHandle value of 1100611139659776. Divide that by 256... 4299262264296 or in hexadecimal, that's 000003E9000003E8 and perhaps you can see the pattern there if we break that into four 8-bit bytes: 0000 03E9 0000 03E8. In this case, 03E9 in decimal is 1001 and 03E8 is 1000.

So this is mostly an aside, but you can convert a "region handle" to coordinates and vice versa, and look it up that way since it's a single field. Although in your case the number of regions is small enough that a linear search is just fine. Actually even in InWorldz, the number of regions is small enough for that.

Vinhold commented 7 years ago

Another option is what I used; I created a simple SQLLite DB and table with a list of all my regions and the processing to automatically keep the table maintained with an accurate list of the regions, including any removed or added regions. Ricky noted that the Land table also has a list of all the regions, however I have not found a foolproof way of identifying the actual regions from any parcels created in the region. That is why I created the SQLLite DB and table with the data I need to track for each region. From my list of regions I can check the region table to see if the entry exists or not. If it is not there, it is offline. If the record exists, Then you can use the IP address and port to query the region for its status. If you get back the expected OK the region is really online. If nothing, it is not online or is inaccessible.

sonjamichelle commented 7 years ago

One big thing my wife has been getting on me about, when we restart a sim inworld it brings the sim down but it never comes back up. I have to log on to the server and bring it back up manually.

Vinhold commented 7 years ago

That has been in discussion for a little while now. There are several solutions for it:

  1. use a batch file to launch the region making it a simple "manager" process. The downside is that the region process does not have ErrorLevel settings to identify when the console is shut down vs. an in-world viewer shutdown request, so the batch file has no accurate way to identify the situation. I am currently using this on my servers: @Echo off :Halcyon Control Batch Program :loop Halcyon.exe %* @echo Error %errorlevel%

if not errorlevel 0 goto loop

Set up a desktop icon to call the batch file and send parms to the batch file: Target: C:\Halcyon.bat --inimaster=..\Halcyon.ini --inifile=.ini --logconfig=.config Start In: C:\

While you are at it, the land management and estate operation does not have any management tools to make it nice to work with. I have to do any estate changes in the DB directly. I have a web designed to handle estate management in user account logon if the account has any regions they "own". I just have not had time yet to write it. It is being put into the full website core I have been working on.

sonjamichelle commented 7 years ago

Maestro, yes that's another package that wouldn't build that required missing libraries and alphabet installers.

Vinhold commented 7 years ago

I suspect you are the first to have actually tried Maestro outside of InWorldz. It is still in development, but is being used for the InWorldz grid operation with zookeeper doing the grid management. Jim would have to fill in any details.

appurist commented 7 years ago

Maestro is even less ready for other grids to pick up and use easily than the core server is. So... 😁 It is written in python, although with some python tools it can be built into a .exe file. I worked on a web user interface for it, extending what was already done, and adding support for recognizing different environments and different settings, so that it could be used to maintain the main grid, beta grid, development, etc. But it currently has four major problems:

In most cases, writing a simple looping .CMD batch file to restart a region is good because it is extremely simple and just works. You can interrupt it with a Ctrl-C if you want to actually let a region shut down.

Something as simple as (region.cmd):

:loop
Halcyon.exe
goto loop
sonjamichelle commented 7 years ago

Kind of like hitting the solution with a hammer, but it works. And the wife is happy, so that's two problems solved! ;-)

sonjamichelle commented 7 years ago

With the 0.9.29 issue and having to quickly update to 0.9.30 I was wondering what is the "official" update process?

Currently here's how I do it:

I pull the branch I want from GitHub Copy the source to a working directory Run runprebuild.bat Compile the sln Rename the resulting bin directory to the resulting release (eg: bin.9.30.6150) Head on over to the server. Copy all my bin directories (bin and bin1 to bin21) to a backup directory Copy over the bin.9.30.6150 directory to my live system directory structure Shutdown my Grid Services. (Grid Server, User Server, Messaging Server, Aperture) Copy the contents of bin.9.30.6150 to bin (where my Grid services reside) replacing files that exist. Restart my Grid services. I then go to the first region in my grid, shut it down. Copy the contents of bin.9.30.6150 to bin1 replacing files that exist. Restart my region. Rinse and repeat until all regions have been updated.

So far this process has worked. Am I far off the "official" process? Am I creating more work for myself? I'd say it took less than an hour to do 21 regions and a grid services directory this morning. I really didn't pay attention to the clock so that's a ballpark estimation.

appurist commented 7 years ago

You don't need to bother with 0.9.29 at all. The releases are cumulative in that you can just apply the latest. It's an update of the code. The 0.9.29 release on GitHub had a problem and I'm not even sure it would load. You can just skip .29 and update to .30.

It's a good point that I don't think it is documented how to update a region with a new release. The usual process should be something like:

The specifics of that are that the release/code files are all .exe, .dll and .pdb files. There are some in subfolders too. So this means:

I'm going to include the batch script I use for my testing machine. I have 4 regions in bin folders, and I run a master update.cmd file which does:

@echo off
START .\UpdateRegion.cmd c:\halcyon BIN BIN
START .\UpdateRegion.cmd c:\halcyon BIN BIN2
START .\UpdateRegion.cmd c:\halcyon BIN BIN3
START .\UpdateRegion.cmd c:\halcyon BIN BIN4

In my case I'm prepping the output region as one of the regions so the first entry passes BIN for both source and destination folder. The second .CMD file checks for that and skips the code delete+copy but does the add-ins cleanup.

The contents of that UpdateRegion.cmd file looks like:

@echo off
rem UpdateRegion c:\halcyon BIN BIN2
rem Updates from %1\%2 to %1\%3

if "%3" == "" goto err

set SRC=%1\%2
set DEST=%1\%3
echo Updating %DEST% from %SRC%
C:
cd %DEST%
if '%2' == '%3' goto SkipForSame

del %DEST%\*.EXE
del %DEST%\*.DLL
del %DEST%\*.PDB
del %DEST%\Physics\*.DLL
del %DEST%\Physics\*.PDB
del %DEST%\Terrain\*.DLL
del %DEST%\Terrain\*.PDB

copy %SRC%\*.EXE %DEST%
copy %SRC%\*.DLL %DEST%
copy %SRC%\*.PDB %DEST%
copy %SRC%\Physics\*.DLL %DEST%\Physics\
copy %SRC%\Physics\*.PDB %DEST%\Physics\
copy %SRC%\Terrain\*.DLL %DEST%\Terrain\
copy %SRC%\Terrain\*.PDB %DEST%\Terrain\

:SkipForSame
rmdir /s /q %DEST%\addin-db-001
rmdir /s /q %DEST%\addin-db-002

echo %3 complete.

goto done

:err
echo Specify the source folder root, destination folder root, then destination bin folder.
echo e.g. UpdateRegion c:\halcyon BIN BIN2
:done

rem pause
EXIT
sonjamichelle commented 7 years ago

I have a user that is trying to log on. I see the Authentication attempt in the user console but she hangs and times out at the region handshake with an error that "something is wrong with the internet" message. This happens with her main account and we even tried creating a new alt account. I can log on to her accounts from my PC. Halcyon is hosted on a remote server in Kansas City, MO so it's not a local vs remote issue. We're both connecting remotely. She can log into InWorldz just fine, so it's not an "internet" issue, it's grid specific. This also happens in Singularity as well as Firestorm.

I tried force logging her off in case she was still logged in from a previous stuck session from the user console. No luck.

appurist commented 7 years ago

I think hanging at the region handshake means that something (such as firewall software) is blocking the return packets from that region process. Either outbound from the region server, or inbound at the viewer machine. If it's working for you, from outside the server network, that means it's probably this user's firewall setup. They should try disabling it completely, temporarily, just long enough to test once to see if that bypasses the issue. Then perhaps add an exception for the viewer or enable a learning mode if the firewall has one. (I recommend ESET by the way).

sonjamichelle commented 7 years ago

I thought about firewall too, but wouldn't it block her connection to InWorldz as well? Seeing as Windows Firewall blocks by program exe (from what I can tell) I'll have her turn off Firewall to see if that's the culprit, then we'll look for an entry. Worth a try. I've seen Windows Firewall cause lots of issues.

appurist commented 7 years ago

Do you know which Windows firewall she is using? Most do not due automatic blocking by program exe, that is the typical user response to enable or disable something by exe for convenience, rather than figuring out which protocols and ports need to be opened, etc. The automatic rules creation is typically by service/port, and depends on a lot of factors. Much of the automatic stuff will provide different levels of strict blocking depending on whether the content is incoming or outgoing, but will often remember outgoing requests and allow their responses etc. However, in the case of UDP, they are independent packets, on different ports, and there is no connection, so there is no context for the incoming packet response, when it returns. So really, the simplest next step is to just disable which ever firewall is in use (many Anti-Virus packages include their own firewall which replaces the default Windows firewall). In this case, I'm pretty sure the outgoing viewer packets are being allowed but the incoming responses to the viewer (specifically the ACK and response to the UseCircuitCode packet) are not getting back to the viewer. So it resends it and eventually gives up. The nice thing about disabling the firewall completely is that the result of trying that is very definitive. If it helps, it's likely new rules need to be added; if it doesn't, it's definitively the wrong track.

sonjamichelle commented 7 years ago

A little bit more info. She disabled the firewall. NoGo. Changed IP's. NoGo. Spoofed IP. NoGo. We (my wife and I) Tried logging in with her account from our tablet and phone, no go. Tried our accounts too. NoGo. NO ACCOUNT could log in. We could only log in from our home PC that was connected to the server pc. Not sure why. Only thing that has happened since last successful logins was a Windows Update install. So I went back and uninstalled the November 2016 Security Monthly Quality Rollup For Windows Server 2012R2 (KB3197874), rebooted, started my grid, loaded up a region and everyone was able to log on again.

appurist commented 7 years ago

That's great to hear, although a bit scary. (!) You able to connect from a different machine on the same local network as the server, but not from outside that network? And the machine that was updated was the one running the server software? I don't really have anything to suggest here if reverting the Microsoft update resolved it, other than to hope others have also run into this and to hope that Microsoft will address it in a future update. However, my quick google search for that update didn't really reveal any suspicious results. Kudos though for recognizing it might be a Windows update and testing the effect of reverting it!

sonjamichelle commented 7 years ago

I recently switched servers. Moved my files from one machine to another. Unfortunately now when I start some of my regions they get as far as "Loading objects from datastore" and "Loading inventory items for region" then crash out. I've tried loading the Whip files from backup. Tried loading the DB from backup and so far nothing seems to be working. Any ideas on how I can get my regions to load again?

Here is the error that it throws from the console:

`10:36:07 - [APPLICATION]: APPLICATION EXCEPTION DETECTED: System.UnhandledExceptionEventArgs

Exception: MySql.Data.MySqlClient.MySqlException (0x80004005): Timeout expired. The timeout period elapsed prior to completion of the opera tion or the server is not responding. ---> System.TimeoutException: Ti meout in IO operation at MySql.Data.MySqlClient.TimedStream.StopTimer() at MySql.Data.MySqlClient.TimedStream.Read(Byte[] buffer, Int32 off set, Int32 count) at System.IO.BufferedStream.Read(Byte[] array, Int32 offset, Int32 count) at MySql.Data.MySqlClient.MySqlStream.ReadFully(Stream stream, Byte [] buffer, Int32 offset, Int32 count) at MySql.Data.MySqlClient.MySqlStream.LoadPacket() at MySql.Data.MySqlClient.MySqlStream.ReadPacket() at MySql.Data.MySqlClient.NativeDriver.FetchDataRow(Int32 statement Id, Int32 columns) at MySql.Data.MySqlClient.ResultSet.GetNextRow() at MySql.Data.MySqlClient.ResultSet.NextRow(CommandBehavior behavio r) at MySql.Data.MySqlClient.MySqlDataReader.Read() at MySql.Data.MySqlClient.ExceptionInterceptor.Throw(Exception exce ption) at MySql.Data.MySqlClient.MySqlConnection.HandleTimeoutOrThreadAbor t(Exception ex) at MySql.Data.MySqlClient.MySqlDataReader.Read() at OpenSim.Data.MySQL.MySQLDataStore.LoadItemsForRegion(UUID region UUID) in C:\Users\Administrator\Desktop\halcyon\OpenSim\Data\MySQL\MyS QLRegionData.cs:line 976 at OpenSim.Data.MySQL.MySQLDataStore.LoadObjects(UUID regionUUID) i n C:\Users\Administrator\Desktop\halcyon\OpenSim\Data\MySQL\MySQLRegio nData.cs:line 937 at OpenSim.Region.Framework.Scenes.Scene.LoadPrimsFromStorage(UUID regionID) in C:\Users\Administrator\Desktop\halcyon\OpenSim\Region\Fra mework\Scenes\Scene.cs:line 2113 at OpenSim.OpenSimBase.CreateRegion(RegionInfo regionInfo, Boolean portadd_flag, Boolean do_post_init, IScene& mscene) in C:\Users\Admini strator\Desktop\halcyon\OpenSim\Base\OpenSimBase.cs:line 470 at OpenSim.OpenSimBase.CreateRegion(RegionInfo regionInfo, Boolean portadd_flag, IScene& scene) in C:\Users\Administrator\Desktop\halcyon \OpenSim\Base\OpenSimBase.cs:line 395 at OpenSim.ApplicationPlugins.LoadRegions.LoadRegionsPlugin.PostIni tialize() in C:\Users\Administrator\Desktop\halcyon\OpenSim\Applicatio nPlugins\LoadRegions\LoadRegionsPlugin.cs:line 119 at OpenSim.OpenSimBase.StartupSpecific() in C:\Users\Administrator\ Desktop\halcyon\OpenSim\Base\OpenSimBase.cs:line 211 at OpenSim.OpenSim.StartupSpecific() in C:\Users\Administrator\Desk top\halcyon\OpenSim\Base\OpenSim.cs:line 163 at OpenSim.Framework.Servers.BaseOpenSimServer.Startup() in C:\User s\Administrator\Desktop\halcyon\OpenSim\Framework\Servers\BaseOpenSimS erver.cs:line 300 at OpenSim.Application.Main(String[] args) in C:\Users\Administrato r\Desktop\halcyon\InWorldz\Halcyon\Application.cs:line 145 InnerException: System.TimeoutException: Timeout in IO operation at MySql.Data.MySqlClient.TimedStream.StopTimer() at MySql.Data.MySqlClient.TimedStream.Read(Byte[] buffer, Int32 off set, Int32 count) at System.IO.BufferedStream.Read(Byte[] array, Int32 offset, Int32 count) at MySql.Data.MySqlClient.MySqlStream.ReadFully(Stream stream, Byte [] buffer, Int32 offset, Int32 count) at MySql.Data.MySqlClient.MySqlStream.LoadPacket() at MySql.Data.MySqlClient.MySqlStream.ReadPacket() at MySql.Data.MySqlClient.NativeDriver.FetchDataRow(Int32 statement Id, Int32 columns) at MySql.Data.MySqlClient.ResultSet.GetNextRow() at MySql.Data.MySqlClient.ResultSet.NextRow(CommandBehavior behavio r) at MySql.Data.MySqlClient.MySqlDataReader.Read()

Application is terminating: True`

Vinhold commented 7 years ago

Looks like the errors are related to not being able to connect to your MySQL DB service / server. That is not a Whip error. My guess is to check your MySQL DB connection string that it is correctly aimed at the place for the Database. Whip stores its data in a folder tree structure, with lots of little files. Changing servers can be a significant disruption on your data paths and connection to Database and Asset services. Especially since there are quite a few references in the configuration files to both DB and Assets and all must be updated to work.

sonjamichelle commented 7 years ago

The connection strings are correct. And only SOME of the regions are having issues. Thing is it's mostly my main regions.

appurist commented 7 years ago

The only things I can think of here, off the top of my head, is if some of them specify localhost or 127.0.0.1, or if some of them have different ports.

The different ports might not have HTTP ACLs set up for them yet. I use a .CMD file like this:

netsh http add urlacl url=http://+:8000/ user=%USERNAME%
netsh http add urlacl url=http://+:8001/ user=%USERNAME%
netsh http add urlacl url=http://+:8002/ user=%USERNAME%
netsh http add urlacl url=http://+:8003/ user=%USERNAME%
netsh http add urlacl url=http://+:8004/ user=%USERNAME%
netsh http add urlacl url=http://+:8005/ user=%USERNAME%
netsh http add urlacl url=http://+:8006/ user=%USERNAME%
netsh http add urlacl url=http://+:8007/ user=%USERNAME%
netsh http add urlacl url=http://+:8008/ user=%USERNAME%
netsh http add urlacl url=http://+:8009/ user=%USERNAME%

netsh http add urlacl url=http://+:9020/ user=%USERNAME%
netsh http add urlacl url=http://+:9021/ user=%USERNAME%
netsh http add urlacl url=http://+:9022/ user=%USERNAME%
netsh http add urlacl url=http://+:9023/ user=%USERNAME%
netsh http add urlacl url=http://+:9024/ user=%USERNAME%
netsh http add urlacl url=http://+:9025/ user=%USERNAME%
netsh http add urlacl url=http://+:9026/ user=%USERNAME%
netsh http add urlacl url=http://+:9027/ user=%USERNAME%
netsh http add urlacl url=http://+:9028/ user=%USERNAME%
netsh http add urlacl url=http://+:9029/ user=%USERNAME%
netsh http add urlacl url=http://+:9030/ user=%USERNAME%
netsh http add urlacl url=http://+:9031/ user=%USERNAME%
netsh http add urlacl url=http://+:9032/ user=%USERNAME%
netsh http add urlacl url=http://+:9033/ user=%USERNAME%
netsh http add urlacl url=http://+:9034/ user=%USERNAME%
netsh http add urlacl url=http://+:9035/ user=%USERNAME%

netsh http add urlacl url=http://+:9500/ user=%USERNAME%
netsh http add urlacl url=http://+:9501/ user=%USERNAME%
netsh http add urlacl url=http://+:9502/ user=%USERNAME%
netsh http add urlacl url=http://+:9503/ user=%USERNAME%
netsh http add urlacl url=http://+:9504/ user=%USERNAME%
netsh http add urlacl url=http://+:9505/ user=%USERNAME%
netsh http add urlacl url=http://+:9506/ user=%USERNAME%
netsh http add urlacl url=http://+:9507/ user=%USERNAME%
netsh http add urlacl url=http://+:9508/ user=%USERNAME%
netsh http add urlacl url=http://+:9509/ user=%USERNAME%
netsh http add urlacl url=http://+:9510/ user=%USERNAME%
netsh http add urlacl url=http://+:9511/ user=%USERNAME%
netsh http add urlacl url=http://+:9512/ user=%USERNAME%
netsh http add urlacl url=http://+:9513/ user=%USERNAME%
netsh http add urlacl url=http://+:9514/ user=%USERNAME%
netsh http add urlacl url=http://+:9515/ user=%USERNAME%

(run as Administrator) If that made a difference to the system (not already set), then the machine will need a restart as well.

sonjamichelle commented 7 years ago

Nope, adding the ACL's didn't make a difference.

When I moved everything over, I tar'ed the directory containing the files, moved it to a backup site. Exported my DB, uploaded it to a backup site. Wiped the server. Reinstalled a new OS. Downloaded the tar file, unpacked it. Downloaded my DB, imported it to my new MySQL server instance. The only thing that changed about the server was the OS that it is running, from Win 2012R2 to Win 2016. IP is the same. I checked all the connection strings, all the references to localhost and everywhere an ip or server is referenced. So far everything checks out. Just 25% of my regions hand at "loading objects from inventory" for about 5 mins, then crash out with the above error.