diff --git a/Classes/IJInventoryWindowController.h b/Classes/IJInventoryWindowController.h index 5144c19..b4e1314 100644 --- a/Classes/IJInventoryWindowController.h +++ b/Classes/IJInventoryWindowController.h @@ -46,6 +46,7 @@ int loadedWorldIndex; NSString *loadedWorldFolder; NSString *attemptedLoadWorldFolder; + NSString *loadedPlayer; } @property (nonatomic, assign) IBOutlet NSSegmentedControl *worldSelectionControl; @@ -57,6 +58,7 @@ @property (nonatomic, assign) IBOutlet NSTableView *itemTableView; @property (nonatomic, retain) NSNumber *worldTime; +@property (nonatomic, retain) NSString *playerName; - (IBAction)menuSelectWorldFromPath:(id)sender; - (IBAction)menuSelectWorld:(id)sender; diff --git a/Classes/IJInventoryWindowController.m b/Classes/IJInventoryWindowController.m index a8fd6a1..6c50e69 100644 --- a/Classes/IJInventoryWindowController.m +++ b/Classes/IJInventoryWindowController.m @@ -60,6 +60,7 @@ [normalInventory release]; [inventory release]; [level release]; + [player release]; [super dealloc]; } @@ -116,6 +117,8 @@ [self willChangeValueForKey:@"worldTime"]; [level release]; level = nil; + [player release]; + player = nil; [inventory release]; inventory = nil; [self didChangeValueForKey:@"worldTime"]; @@ -136,12 +139,18 @@ [self willChangeValueForKey:@"worldTime"]; /* Now search for first player .dat file (but by default try to load from level.dat */ - NSString *playerPath = [IJMinecraftLevel pathForLevelDatAtFolder:worldPath]; +#if 1 + loadedPlayer = nil; + + NSString *playerPath = [IJMinecraftLevel pathForPlayer:loadedPlayer withWorld:worldPath]; +#else + NSString *playerPath = [worldPath stringByAppendingString:@"/players/Godzil.dat"]; +#endif NSData *playerFileData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:playerPath]]; - if (!fileData) + if (!playerFileData) { // Error loading - NSBeginCriticalAlertSheet(@"Error loading world.", @"Dismiss", nil, nil, self.window, nil, nil, nil, nil, @"InsideJob was unable to load the level at %@.", levelPath); + NSBeginCriticalAlertSheet(@"Error loading player.", @"Dismiss", nil, nil, self.window, nil, nil, nil, nil, @"InsideJob was unable to load the level at %@.", playerPath); return; } @@ -190,7 +199,7 @@ [self setDocumentEdited:NO]; statusTextField.stringValue = @""; - loadedWorldFolder = worldPath; + loadedWorldFolder = [worldPath copy]; } - (void)loadWorldAtIndex:(int)worldIndex @@ -204,19 +213,20 @@ - (void)saveWorld { -#if 0 - int worldIndex = loadedWorldIndex; + NSString *worldPath = loadedWorldFolder; + if (inventory == nil) return; // no world loaded, nothing to save - if (![IJMinecraftLevel checkSessionLockAtIndex:worldIndex value:sessionLockValue]) + if (![IJMinecraftLevel checkSessionLockAtFolder:worldPath value:sessionLockValue]) { NSBeginCriticalAlertSheet(@"Another application has modified this world.", @"Dismiss", nil, nil, self.window, nil, nil, nil, nil, @"The session lock was changed by another application."); return; } - NSString *levelPath = [IJMinecraftLevel pathForLevelDatAtIndex:worldIndex]; - + NSString *levelPath = [IJMinecraftLevel pathForLevelDatAtFolder:worldPath]; + NSString *playerPath = [IJMinecraftLevel pathForPlayer:loadedPlayer withWorld:worldPath]; + NSMutableArray *newInventory = [NSMutableArray array]; for (NSArray *items in [NSArray arrayWithObjects:armorInventory, quickInventory, normalInventory, nil]) @@ -228,17 +238,29 @@ } } - [level setInventory:newInventory]; + [player setInventory:newInventory]; - NSString *backupPath = [levelPath stringByAppendingPathExtension:@"insidejobbackup"]; + NSString *backupLevelPath = [levelPath stringByAppendingPathExtension:@"insidejobbackup"]; + NSString *backupPlayerPath = [playerPath stringByAppendingPathExtension:@"insidejobbackup"]; BOOL success = NO; NSError *error = nil; // Remove a previously-created .insidejobbackup, if it exists: - if ([[NSFileManager defaultManager] fileExistsAtPath:backupPath]) + if ([[NSFileManager defaultManager] fileExistsAtPath:backupLevelPath]) { - success = [[NSFileManager defaultManager] removeItemAtPath:backupPath error:&error]; + success = [[NSFileManager defaultManager] removeItemAtPath:backupLevelPath error:&error]; + if (!success) + { + NSLog(@"%s:%d %@", __PRETTY_FUNCTION__, __LINE__, [error localizedDescription]); + NSBeginCriticalAlertSheet(@"An error occurred while saving.", @"Dismiss", nil, nil, self.window, nil, nil, nil, nil, @"Inside Job was unable to remove the prior backup of this level file:\n%@", [error localizedDescription]); + return; + } + } + // Remove a previously-created .insidejobbackup, if it exists: + if ([[NSFileManager defaultManager] fileExistsAtPath:backupLevelPath]) + { + success = [[NSFileManager defaultManager] removeItemAtPath:backupPlayerPath error:&error]; if (!success) { NSLog(@"%s:%d %@", __PRETTY_FUNCTION__, __LINE__, [error localizedDescription]); @@ -248,22 +270,38 @@ } // Create the backup: - success = [[NSFileManager defaultManager] copyItemAtPath:levelPath toPath:backupPath error:&error]; + success = [[NSFileManager defaultManager] copyItemAtPath:levelPath toPath:backupLevelPath error:&error]; if (!success) { NSLog(@"%s:%d %@", __PRETTY_FUNCTION__, __LINE__, [error localizedDescription]); NSBeginCriticalAlertSheet(@"An error occurred while saving.", @"Dismiss", nil, nil, self.window, nil, nil, nil, nil, @"Inside Job was unable to create a backup of the existing level file:\n%@", [error localizedDescription]); return; } - + + success = [[NSFileManager defaultManager] copyItemAtPath:playerPath toPath:backupPlayerPath error:&error]; + if (!success) + { + NSLog(@"%s:%d %@", __PRETTY_FUNCTION__, __LINE__, [error localizedDescription]); + NSBeginCriticalAlertSheet(@"An error occurred while saving.", @"Dismiss", nil, nil, self.window, nil, nil, nil, nil, @"Inside Job was unable to create a backup of the existing level file:\n%@", [error localizedDescription]); + return; + } + // Write the new level.dat out: - success = [[level writeData] writeToURL:[NSURL fileURLWithPath:levelPath] options:0 error:&error]; + success = [[player writeData] writeToURL:[NSURL fileURLWithPath:levelPath] options:0 error:&error]; + if (!success) { NSLog(@"%s:%d %@", __PRETTY_FUNCTION__, __LINE__, [error localizedDescription]); NSError *restoreError = nil; - success = [[NSFileManager defaultManager] copyItemAtPath:backupPath toPath:levelPath error:&restoreError]; + success = [[NSFileManager defaultManager] copyItemAtPath:backupLevelPath toPath:levelPath error:&restoreError]; + if (!success) + { + NSLog(@"%s:%d %@", __PRETTY_FUNCTION__, __LINE__, [restoreError localizedDescription]); + NSBeginCriticalAlertSheet(@"An error occurred while saving.", @"Dismiss", nil, nil, self.window, nil, nil, nil, nil, @"Inside Job was unable to save to the existing level file, and the backup could not be restored.\n%@\n%@", [error localizedDescription], [restoreError localizedDescription]); + } + + success = [[NSFileManager defaultManager] copyItemAtPath:backupPlayerPath toPath:playerPath error:&restoreError]; if (!success) { NSLog(@"%s:%d %@", __PRETTY_FUNCTION__, __LINE__, [restoreError localizedDescription]); @@ -278,7 +316,6 @@ [self setDocumentEdited:NO]; statusTextField.stringValue = @"Saved."; -#endif } - (void)setDocumentEdited:(BOOL)edited @@ -327,7 +364,6 @@ } /* Now try to open the world... */ [self loadWorldAtFolder:[[panel directoryURL] path]]; - } } @@ -377,6 +413,18 @@ [self setDocumentEdited:YES]; } +- (NSNumber *)worldTime +{ + return [level worldTimeContainer].numberValue; +} +- (void)setWorldTime:(NSNumber *)number +{ + [self willChangeValueForKey:@"worldTime"]; + [level worldTimeContainer].numberValue = number; + [self didChangeValueForKey:@"worldTime"]; + [self setDocumentEdited:YES]; +} + #pragma mark - #pragma mark IJInventoryViewDelegate diff --git a/Classes/IJMinecraftLevel.h b/Classes/IJMinecraftLevel.h index e6c2580..228b764 100644 --- a/Classes/IJMinecraftLevel.h +++ b/Classes/IJMinecraftLevel.h @@ -21,6 +21,7 @@ + (NSString *)pathForLevelDatAtFolder:(NSString *)worldPath; + (NSString *)pathForSessionLockAtFolder:(NSString *)worldPath; ++ (NSString *)pathForPlayer:(NSString *)loadedPlayer withWorld:(NSString *)worldPath; + (BOOL)worldExistsAtFolder:(NSString *)worldPath; diff --git a/Classes/IJMinecraftLevel.m b/Classes/IJMinecraftLevel.m index 988e321..05f1297 100644 --- a/Classes/IJMinecraftLevel.m +++ b/Classes/IJMinecraftLevel.m @@ -29,8 +29,19 @@ // - compound "Player" // - list "Inventory" // * + // SMP Player have not the same structure, there is no "DATA" compound, nor "player" + NBTContainer *playerCompound; NBTContainer *dataCompound = [self childNamed:@"Data"]; - NBTContainer *playerCompound = [dataCompound childNamed:@"Player"]; + if (dataCompound != nil) + { + playerCompound = [dataCompound childNamed:@"Player"]; + } + else + { + NSLog(@"Player file is from a SMP file, not level.dat one"); + playerCompound = self; + } + NBTContainer *inventoryList = [playerCompound childNamed:@"Inventory"]; // TODO: Check for error conditions here. return inventoryList; @@ -126,6 +137,15 @@ return [worldPath stringByAppendingPathComponent:@"session.lock"]; } ++ (NSString *)pathForPlayer:(NSString *)loadedPlayer withWorld:(NSString *)worldPath; +{ + /* loadedPlayer == nil, we use level.dat, or else we use the name */ + if (loadedPlayer == nil) + return [self pathForLevelDatAtFolder:worldPath]; + + return [[[worldPath stringByAppendingPathComponent:@"players"] stringByAppendingPathComponent:loadedPlayer] stringByAppendingPathExtension:@".dat"]; +} + + (BOOL)worldExistsAtFolder:(NSString *)worldPath { return [[NSFileManager defaultManager] fileExistsAtPath:[[self class] pathForLevelDatAtFolder:worldPath]]; diff --git a/Classes/NBTContainer.m b/Classes/NBTContainer.m index bfe9cc8..f966d8f 100644 --- a/Classes/NBTContainer.m +++ b/Classes/NBTContainer.m @@ -12,7 +12,7 @@ #ifndef NBT_LOGGING -#define NBT_LOGGING 0 +#define NBT_LOGGING 0 #endif #if NBT_LOGGING diff --git a/English.lproj/MainMenu.xib b/English.lproj/MainMenu.xib index 472dbb3..272d3fd 100644 --- a/English.lproj/MainMenu.xib +++ b/English.lproj/MainMenu.xib @@ -554,8 +554,7 @@ 266 {{303, 369}, {274, 14}} - - + YES 68288064 @@ -592,8 +591,7 @@ 268 {{101, 327}, {85, 19}} - - + YES -1804468671 @@ -675,7 +673,7 @@ MQA - + 6 System textColor @@ -688,7 +686,6 @@ 268 {{56, 329}, {40, 14}} - YES @@ -701,12 +698,28 @@ + + + 268 + {{203, 329}, {43, 14}} + + + YES + + 68288064 + 71435264 + Player : + + + + + + 10 {{0, 355}, {585, 5}} - {0, 0} @@ -734,8 +747,7 @@ 268 {{11, 364}, {195, 25}} - - + YES 67239424 @@ -783,7 +795,6 @@ 268 {{11, 58}, {360, 120}} - IJInventoryView @@ -792,7 +803,6 @@ 268 {{11, 10}, {360, 40}} - IJInventoryView @@ -801,7 +811,6 @@ 268 {{11, 186}, {40, 160}} - IJInventoryView @@ -810,7 +819,6 @@ 265 {{379, 327}, {195, 22}} - YES @@ -884,7 +892,6 @@ 4352 {193, 307} - YES @@ -1064,7 +1071,6 @@ {{1, 1}, {193, 307}} - @@ -1075,7 +1081,6 @@ -2147483392 {{191, 17}, {15, 365}} - _doScroller: @@ -1086,7 +1091,6 @@ -2147483392 {{1, 382}, {190, 15}} - 1 @@ -1096,7 +1100,6 @@ {{379, 10}, {195, 309}} - 562 @@ -1109,8 +1112,7 @@ -2147483380 {{212, 368}, {88, 18}} - - + YES 67239424 @@ -1133,10 +1135,56 @@ 25 + + + 268 + {{351, 326}, {20, 21}} + + + YES + + -2080244224 + 134217728 + + + + -2033434369 + 162 + + NSImage + NSUser + + + + 400 + 75 + + + + + 268 + {{251, 327}, {96, 19}} + + + YES + + -1804468671 + 272630784 + + + LucidaGrande + 11 + 16 + + + YES + + + + {{7, 11}, {585, 396}} - {{0, 0}, {1440, 878}} @@ -1524,6 +1572,22 @@ 694 + + + value: playerName + + + + + + value: playerName + value + playerName + 2 + + + 710 + @@ -1850,6 +1914,9 @@ + + + @@ -2159,6 +2226,48 @@ + + 698 + + + YES + + + + + + 699 + + + + + 705 + + + YES + + + + + + 706 + + + + + 707 + + + YES + + + + + + 708 + + + @@ -2309,6 +2418,13 @@ 693.IBPluginDependency 695.IBPluginDependency 696.IBPluginDependency + 698.IBPluginDependency + 698.IBViewBoundsToFrameTransform + 699.IBPluginDependency + 705.IBPluginDependency + 706.IBPluginDependency + 707.IBPluginDependency + 708.IBPluginDependency 75.IBPluginDependency 75.ImportedFromIB2 81.IBEditorWindowLastContentRect @@ -2490,6 +2606,15 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDBQAAw6qAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin {{483, 773}, {178, 63}} com.apple.InterfaceBuilder.CocoaPlugin @@ -2513,250 +2638,9 @@ - 696 - - - - YES - - IJInventoryView - NSView - - IBProjectSource - ./Classes/IJInventoryView.h - - - - IJInventoryWindowController - NSWindowController - - YES - - YES - itemTableViewDoubleClicked: - makeSearchFieldFirstResponder: - menuSelectWorld: - menuSelectWorldFromPath: - updateItemSearchFilter: - worldSelectionChanged: - - - YES - id - id - id - id - id - id - - - - YES - - YES - itemTableViewDoubleClicked: - makeSearchFieldFirstResponder: - menuSelectWorld: - menuSelectWorldFromPath: - updateItemSearchFilter: - worldSelectionChanged: - - - YES - - itemTableViewDoubleClicked: - id - - - makeSearchFieldFirstResponder: - id - - - menuSelectWorld: - id - - - menuSelectWorldFromPath: - id - - - updateItemSearchFilter: - id - - - worldSelectionChanged: - id - - - - - YES - - YES - armorView - inventoryView - itemSearchField - itemTableView - quickView - statusTextField - worldSelectionControl - - - YES - IJInventoryView - IJInventoryView - NSSearchField - NSTableView - IJInventoryView - NSTextField - NSSegmentedControl - - - - YES - - YES - armorView - inventoryView - itemSearchField - itemTableView - quickView - statusTextField - worldSelectionControl - - - YES - - armorView - IJInventoryView - - - inventoryView - IJInventoryView - - - itemSearchField - NSSearchField - - - itemTableView - NSTableView - - - quickView - IJInventoryView - - - statusTextField - NSTextField - - - worldSelectionControl - NSSegmentedControl - - - - - IBProjectSource - ./Classes/IJInventoryWindowController.h - - - - IJTableView - NSTableView - - IBProjectSource - ./Classes/IJTableView.h - - - - InsideJobAppDelegate - NSObject - - inventoryWindowController - IJInventoryWindowController - - - inventoryWindowController - - inventoryWindowController - IJInventoryWindowController - - - - IBProjectSource - ./Classes/InsideJobAppDelegate.h - - - - NSDocument - - YES - - YES - printDocument: - revertDocumentToSaved: - runPageLayout: - saveDocument: - saveDocumentAs: - saveDocumentTo: - - - YES - id - id - id - id - id - id - - - - YES - - YES - printDocument: - revertDocumentToSaved: - runPageLayout: - saveDocument: - saveDocumentAs: - saveDocumentTo: - - - YES - - printDocument: - id - - - revertDocumentToSaved: - id - - - runPageLayout: - id - - - saveDocument: - id - - - saveDocumentAs: - id - - - saveDocumentTo: - id - - - - - IBProjectSource - ./Classes/NSDocument.h - - - + 710 + 0 IBCocoaFramework @@ -2776,12 +2660,14 @@ NSMenuCheckmark NSMenuMixedState NSSwitch + NSUser YES {9, 8} {7, 2} {15, 15} + {32, 32} diff --git a/InsideJob-Info.plist b/InsideJob-Info.plist index 3f9849c..57f6c5e 100644 --- a/InsideJob-Info.plist +++ b/InsideJob-Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0.2-gdz + 1.0.2-smp CFBundleSignature ???? CFBundleURLTypes