Skip to content

Commit

Permalink
Merge pull request #199 from UOX3DevTeam/resource_loading_saving_update
Browse files Browse the repository at this point in the history
Resource loading saving update
  • Loading branch information
Xoduz authored Sep 3, 2023
2 parents 8b7539e + 4e3d6dd commit 320bfbe
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 72 deletions.
38 changes: 38 additions & 0 deletions make/XCode/uox3.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@

/* Begin PBXFileReference section */
56BA2FB52A95BDF70064EB36 /* jscript.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = jscript.xcodeproj; path = ../../spidermonkey/make/XCode/jscript/jscript.xcodeproj; sourceTree = "<group>"; };
56C9E3D52A9C8FF0004D9F38 /* CMakeLists.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = CMakeLists.txt; path = ../cmake/CMakeLists.txt; sourceTree = "<group>"; };
56C9E3D82A9C9022004D9F38 /* uox3.sln */ = {isa = PBXFileReference; lastKnownFileType = text; name = uox3.sln; path = ../VS2022/uox3.sln; sourceTree = "<group>"; };
56C9E3D92A9C9022004D9F38 /* uox3.vcxproj */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = uox3.vcxproj; path = ../VS2022/uox3.vcxproj; sourceTree = "<group>"; };
56C9E3DA2A9C9022004D9F38 /* uox3.vcxproj.filters */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = uox3.vcxproj.filters; path = ../VS2022/uox3.vcxproj.filters; sourceTree = "<group>"; };
56C9E3DB2A9C9035004D9F38 /* uox3.vcxproj */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = uox3.vcxproj; path = ../VS2017/uox3.vcxproj; sourceTree = "<group>"; };
56C9E3DC2A9C9035004D9F38 /* uox3.vcxproj.filters */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = uox3.vcxproj.filters; path = ../VS2017/uox3.vcxproj.filters; sourceTree = "<group>"; };
56C9E3DD2A9C9035004D9F38 /* uox3.sln */ = {isa = PBXFileReference; lastKnownFileType = text; name = uox3.sln; path = ../VS2017/uox3.sln; sourceTree = "<group>"; };
648153C929466EF400784170 /* libjscript.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libjscript.a; sourceTree = BUILT_PRODUCTS_DIR; };
64A9006A293E3DA3009B54DA /* uox3 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = uox3; sourceTree = BUILT_PRODUCTS_DIR; };
64A90075293E3DD4009B54DA /* ai.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ai.cpp; sourceTree = "<group>"; };
Expand Down Expand Up @@ -305,9 +312,40 @@
name = Products;
sourceTree = "<group>";
};
56C9E3D22A9C8FD5004D9F38 /* makestuff */ = {
isa = PBXGroup;
children = (
56C9E3D52A9C8FF0004D9F38 /* CMakeLists.txt */,
56C9E3D72A9C9004004D9F38 /* vs2017 */,
56C9E3D62A9C8FF7004D9F38 /* vs2022 */,
);
name = makestuff;
sourceTree = "<group>";
};
56C9E3D62A9C8FF7004D9F38 /* vs2022 */ = {
isa = PBXGroup;
children = (
56C9E3D82A9C9022004D9F38 /* uox3.sln */,
56C9E3D92A9C9022004D9F38 /* uox3.vcxproj */,
56C9E3DA2A9C9022004D9F38 /* uox3.vcxproj.filters */,
);
name = vs2022;
sourceTree = "<group>";
};
56C9E3D72A9C9004004D9F38 /* vs2017 */ = {
isa = PBXGroup;
children = (
56C9E3DD2A9C9035004D9F38 /* uox3.sln */,
56C9E3DB2A9C9035004D9F38 /* uox3.vcxproj */,
56C9E3DC2A9C9035004D9F38 /* uox3.vcxproj.filters */,
);
name = vs2017;
sourceTree = "<group>";
};
64A90061293E3DA3009B54DA = {
isa = PBXGroup;
children = (
56C9E3D22A9C8FD5004D9F38 /* makestuff */,
64A90074293E3DD4009B54DA /* source */,
64A9006B293E3DA3009B54DA /* Products */,
64A9016B293E3EED009B54DA /* Frameworks */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "YES"
customWorkingDirectory = "/Users/charleskerr/Documents/projects/official/data"
customWorkingDirectory = "/Users/charles/Development/projects/official/test/data"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
Expand Down
4 changes: 4 additions & 0 deletions source/Changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
28/08/2023 - punt
Replaced all routine calls with a specific type of stream ifstream/ofstream to the generic istream/ostream for flexibility
Modernized region resource loading/saving code

24/08/2023 - punt
Fixed a memory leak with regions.cpp, related to worldsaves

Expand Down
1 change: 1 addition & 0 deletions source/MultiMul.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "UOPData.hpp"
#include "mapclasses.h"
class TileInfo;
class CTile;
//==================================================================================================
// MultiItem_st
//==================================================================================================
Expand Down
131 changes: 61 additions & 70 deletions source/regions.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
#include "regions.h"

#include <algorithm>
#include <filesystem>
#include <vector>

#include "uox3.h"
#include "classes.h"
#include "regions.h"
#include "StringUtility.hpp"
#include "ObjectFactory.h"
#include <filesystem>
#include <vector>

using namespace std::string_literals;

#define DEBUG_REGIONS 0

CMapHandler *MapRegion;
Expand Down Expand Up @@ -323,30 +329,27 @@ MapResource_st& CMapWorld::GetResource( SI16 x, SI16 y )
//o------------------------------------------------------------------------------------------------o
void CMapWorld::SaveResources( UI08 worldNum )
{
char wBuffer[2];
const std::string resourceFile = cwmWorldState->ServerData()->Directory( CSDDP_SHARED ) + "resource[" + std::to_string( worldNum ) + "].bin";
std::ofstream toWrite( resourceFile.c_str(), std::ios::out | std::ios::trunc | std::ios::binary );

if( toWrite )
auto resourceFile = std::filesystem::path( cwmWorldState->ServerData()->Directory( CSDDP_SHARED ) + "resource["s + std::to_string( worldNum ) + "].bin"s );
auto output = std::ofstream( resourceFile.string(), std::ios::binary );
auto buffer = std::vector<SI16>( 3, 0 );
if( output.is_open() )
{
for( std::vector<MapResource_st>::const_iterator mIter = mapResources.begin(); mIter != mapResources.end(); ++mIter )
for( auto iter = mapResources.begin(); iter != mapResources.end(); iter++ )
{
wBuffer[0] = static_cast<SI08>(( *mIter ).oreAmt >> 8 );
wBuffer[1] = static_cast<SI08>(( *mIter ).oreAmt % 256 );
toWrite.write(( const char * )&wBuffer, 2 );

wBuffer[0] = static_cast<SI08>(( *mIter ).logAmt >> 8 );
wBuffer[1] = static_cast<SI08>(( *mIter ).logAmt % 256 );
toWrite.write(( const char * )&wBuffer, 2 );

wBuffer[0] = static_cast<SI08>(( *mIter ).fishAmt >> 8 );
wBuffer[1] = static_cast<SI08>(( *mIter ).fishAmt % 256 );
toWrite.write(( const char * )&wBuffer, 2 );
}
toWrite.close();
}
else // Can't save resources
buffer[0] = iter->oreAmt;
std::reverse( reinterpret_cast<char*>( buffer.data()), reinterpret_cast<char*>( buffer.data()) + 2 ); // Make it big endian
buffer[1] = iter->logAmt;
std::reverse( reinterpret_cast<char*>( buffer.data()) + 2, reinterpret_cast<char*>( buffer.data()) + 4 );
buffer[2] = iter->fishAmt;
std::reverse( reinterpret_cast<char*>( buffer.data()) + 4, reinterpret_cast<char*>( buffer.data()) + 6 );
// Now write it
output.write( reinterpret_cast<char*>( buffer.data()), buffer.size() * 2 );
}
}
else
{
// Can't save resources
Console.Error( "Failed to open resource.bin for writing" );
}
}
Expand All @@ -359,54 +362,42 @@ void CMapWorld::SaveResources( UI08 worldNum )
//o------------------------------------------------------------------------------------------------o
void CMapWorld::LoadResources( UI08 worldNum )
{
const SI16 resOre = cwmWorldState->ServerData()->ResOre();
const SI16 resLog = cwmWorldState->ServerData()->ResLogs();
const SI16 resFish = cwmWorldState->ServerData()->ResFish();
const UI32 oreTime = BuildTimeValue( static_cast<R32>( cwmWorldState->ServerData()->ResOreTime() ));
const UI32 logTime = BuildTimeValue( static_cast<R32>( cwmWorldState->ServerData()->ResLogTime() ));
const UI32 fishTime = BuildTimeValue( static_cast<R32>( cwmWorldState->ServerData()->ResFishTime() ));
const std::string resourceFile = cwmWorldState->ServerData()->Directory( CSDDP_SHARED ) + std::string("resource[") + oldstrutil::number( worldNum ) + std::string("].bin");

char rBuffer[2];
std::ifstream toRead ( resourceFile.c_str(), std::ios::in | std::ios::binary );

bool fileExists = ( toRead.is_open() );

if( fileExists )
{
toRead.seekg( 0, std::ios::beg );
}

for( std::vector<MapResource_st>::iterator mIter = mapResources.begin(); mIter != mapResources.end(); ++mIter )
mapResources = std::vector<MapResource_st>( mapResources.size(),
MapResource_st( cwmWorldState->ServerData()->ResOre(), cwmWorldState->ServerData()->ResLogs(),
cwmWorldState->ServerData()->ResFish(), BuildTimeValue( static_cast<R32>( cwmWorldState->ServerData()->ResOreTime() )),
BuildTimeValue( static_cast<R32>( cwmWorldState->ServerData()->ResLogTime() )), BuildTimeValue( static_cast<R32>( cwmWorldState->ServerData()->ResFishTime() ))));

auto resourceFile = std::filesystem::path( cwmWorldState->ServerData()->Directory( CSDDP_SHARED ) + "resource["s + oldstrutil::number( worldNum ) + "].bin"s );

// The data is grouped as three shorts (for each resource), so we read in that format
auto buffer = std::vector<SI16>( 3, 0 );
auto input = std::ifstream( resourceFile.string(), std::ios::binary );

// We want to get the iteratro for the first mapResources ;
auto iter = mapResources.begin();
if( input.is_open() )
{
if( fileExists )
{
toRead.read( rBuffer, 2 );
( *mIter ).oreAmt = (( rBuffer[0] << 8 ) + rBuffer[1] );

toRead.read( rBuffer, 2 );
( *mIter ).logAmt = (( rBuffer[0] << 8 ) + rBuffer[1] );

toRead.read( rBuffer, 2 );
( *mIter ).fishAmt = (( rBuffer[0] << 8 ) + rBuffer[1] );

fileExists = toRead.eof();
}
else
while( input.good() && !input.eof() && iter != mapResources.end() )
{
( *mIter ).oreAmt = resOre;
( *mIter ).logAmt = resLog;
( *mIter ).fishAmt = resFish;
}
// No need to preserve time. Do a refresh automatically
( *mIter ).oreTime = oreTime;
( *mIter ).logTime = logTime;
( *mIter ).fishTime = fishTime;
}
if( fileExists )
{
toRead.close();
}
input.read( reinterpret_cast<char*>( buffer.data() ), buffer.size() * 2 );
if( input.gcount() != buffer.size() * 2 )
{
// We had issues reading the full amount, break out of this
break;
}

// For whatever reason the resources are stored in big endidan, which on int/arm machines , we need little endian, so reverse them
std::for_each( buffer.begin(), buffer.end(), []( SI16 &value ) {
std::reverse( reinterpret_cast<char*>( &value ), reinterpret_cast<char*>( &value ) + 2 );
});

// Now set the values
( *iter ).oreAmt = buffer[0];
( *iter ).logAmt = buffer[1];
( *iter ).fishAmt = buffer[2];
iter++;
}
}
}

//o------------------------------------------------------------------------------------------------o
Expand Down
3 changes: 2 additions & 1 deletion source/regions.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ struct MapResource_st
SI16 fishAmt;
UI32 fishTime;

MapResource_st() : oreAmt( 0 ), oreTime( 0 ), logAmt( 0 ), logTime( 0 ), fishAmt( 0 ), fishTime( 0 )
MapResource_st( SI16 defOre = 0, SI16 defLog = 0, SI16 defFish = 0, UI32 defOreTime = 0, UI32 defLogTIme = 0, UI32 defFishTIme = 0 ) :
oreAmt( defOre ), oreTime( defOreTime ), logAmt( defLog ), logTime( defLogTIme ), fishAmt( defFish ), fishTime( defFishTIme )
{
}
};
Expand Down

0 comments on commit 320bfbe

Please sign in to comment.