2021-04-25 22:59:36 -05:00
using OwlCore.AbstractUI.Models ;
using System ;
using System.Collections.Generic ;
using System.IO ;
using System.Threading.Tasks ;
using static ZuneModCore . Mods . FeaturesOverrideMod ;
namespace ZuneModCore.Mods
{
public class WebservicesMod : Mod
{
private const int ZUNESERVICES_ENDPOINTS_BLOCK_OFFSET = 0x14D60 ;
private const int ZUNESERVICES_ENDPOINTS_BLOCK_LENGTH = 0x884 ;
public override string Id => nameof ( WebservicesMod );
public override string Title => "Community Webservices" ;
public override string Description => "Partially restores online features such as the Marketplace by patching the Zune desktop software " +
"to use the community's recreation of Microsoft's Zune servers at zunes.tk (instead of zune.net)." ;
2021-04-26 18:05:19 -05:00
public override string Author => "Joshua \"Yoshi\" Askharoun" ;
2021-04-25 22:59:36 -05:00
public override AbstractUIElementGroup ? OptionsUI => null ;
public override IReadOnlyList < Type >? DependentMods => null ;
2021-04-26 04:28:43 -05:00
public override Task < string? > Apply ()
2021-04-25 22:59:36 -05:00
{
2021-04-26 04:28:43 -05:00
// Verify that ZuneServices.dll exists
2021-04-25 22:59:36 -05:00
FileInfo zsDllInfo = new ( Path . Combine ( ZuneInstallDir , "ZuneService.dll" ));
if (! zsDllInfo . Exists )
2021-04-26 04:28:43 -05:00
{
return Task . FromResult < string? >( $"The file '{zsDllInfo.FullName}' does not exist." );
}
2021-04-25 22:59:36 -05:00
2021-05-30 23:48:48 -05:00
// Make a backup if it doesn't already exist
FileInfo zsDllBackupInfo = new ( Path . Combine ( StorageDirectory , "ZuneService.original.dll" ));
if ( zsDllBackupInfo . Exists )
{
File . Copy ( zsDllInfo . FullName , zsDllBackupInfo . FullName , true );
}
2021-04-25 22:59:36 -05:00
2021-04-26 04:28:43 -05:00
try
{
// Open the file
using FileStream zsDll = zsDllInfo . Open ( FileMode . Open );
using BinaryWriter zsDllWriter = new ( zsDll );
using BinaryReader zsDllReader = new ( zsDll );
// Verify that the DLL is from v4.8 (other versions not tested)
zsDllReader . BaseStream . Position = 0x12C824 ;
2021-04-26 18:05:19 -05:00
var versionBytes = zsDllReader . ReadBytes ( 6 );
2021-04-26 04:28:43 -05:00
if ( versionBytes [ 0 ] != '4' || versionBytes [ 2 ] != '.' || versionBytes [ 4 ] != '8' )
{
return Task . FromResult < string? >( "This mod has not been tested on versions earlier than 4.8." );
}
// Patch ZuneServices.dll to use zunes.tk instead of zune.net
zsDllReader . BaseStream . Position = ZUNESERVICES_ENDPOINTS_BLOCK_OFFSET ;
string endpointBlock = System . Text . Encoding . Unicode . GetString ( zsDllReader . ReadBytes ( ZUNESERVICES_ENDPOINTS_BLOCK_LENGTH ));
endpointBlock = endpointBlock . Replace ( "zune.net" , "zunes.tk" );
byte [] endpointBytes = System . Text . Encoding . Unicode . GetBytes ( endpointBlock );
if ( endpointBytes . Length != ZUNESERVICES_ENDPOINTS_BLOCK_LENGTH )
{
return Task . FromResult < string? >( "Failed to safely overwrite strings in DLL." );
}
zsDllWriter . Seek ( ZUNESERVICES_ENDPOINTS_BLOCK_OFFSET , SeekOrigin . Begin );
zsDllWriter . Write ( endpointBytes );
2021-04-25 22:59:36 -05:00
2021-04-26 04:28:43 -05:00
// Enable all feature overrides affected by new servers
2021-05-06 02:36:14 -05:00
bool setOverrideSuccess = true ;
setOverrideSuccess &= SetFeatureOverride ( "Apps" , true );
setOverrideSuccess &= SetFeatureOverride ( "Channels" , true );
setOverrideSuccess &= SetFeatureOverride ( "Games" , true );
setOverrideSuccess &= SetFeatureOverride ( "Marketplace" , true );
setOverrideSuccess &= SetFeatureOverride ( "Music" , true );
setOverrideSuccess &= SetFeatureOverride ( "MusicVideos" , true );
setOverrideSuccess &= SetFeatureOverride ( "Podcasts" , true );
setOverrideSuccess &= SetFeatureOverride ( "Social" , true );
setOverrideSuccess &= SetFeatureOverride ( "Videos" , true );
if ( setOverrideSuccess != true )
{
return Task . FromResult < string? >( "Unable to set feature overrides. The mod was successful, but you may not be able to see it in the Zune Software." );
}
2021-04-25 22:59:36 -05:00
2021-04-26 04:28:43 -05:00
return Task . FromResult < string? >( null );
}
2021-04-26 17:02:21 -05:00
catch ( IOException )
2021-04-26 04:28:43 -05:00
{
2021-04-26 17:02:21 -05:00
return Task . FromResult < string? >( $"Unable to replace '{zsDllInfo.FullName}'. Verify that the Zune software is not running and try again." );
2021-04-26 04:28:43 -05:00
}
catch ( Exception ex )
{
return Task . FromResult < string? >( ex . Message );
}
2021-04-25 22:59:36 -05:00
}
2021-04-26 04:28:43 -05:00
public override Task < string? > Reset ()
2021-04-25 22:59:36 -05:00
{
2021-04-26 17:02:21 -05:00
string zsDllPath = Path . Combine ( ZuneInstallDir , "ZuneService.dll" );
try
{
// Copy backup to application folder
File . Copy ( Path . Combine ( StorageDirectory , "ZuneService.original.dll" ), zsDllPath , true );
2021-04-26 05:09:48 -05:00
2021-04-26 17:02:21 -05:00
// Disable all feature overrides affected by new servers
2021-05-06 02:36:14 -05:00
bool setOverrideSuccess = true ;
setOverrideSuccess &= SetFeatureOverride ( "Apps" , false );
setOverrideSuccess &= SetFeatureOverride ( "Channels" , false );
setOverrideSuccess &= SetFeatureOverride ( "Games" , false );
setOverrideSuccess &= SetFeatureOverride ( "Marketplace" , false );
setOverrideSuccess &= SetFeatureOverride ( "Music" , false );
setOverrideSuccess &= SetFeatureOverride ( "MusicVideos" , false );
setOverrideSuccess &= SetFeatureOverride ( "Podcasts" , false );
setOverrideSuccess &= SetFeatureOverride ( "Social" , false );
setOverrideSuccess &= SetFeatureOverride ( "Videos" , false );
if ( setOverrideSuccess != true )
{
return Task . FromResult < string? >( "Unable to reset feature overrides. The mod was successfully removed, but you may still be able to see it in the Zune Software." );
}
2021-04-26 05:09:48 -05:00
2021-04-26 17:02:21 -05:00
return Task . FromResult < string? >( null );
}
catch ( IOException )
{
return Task . FromResult < string? >( $"Unable to replace '{zsDllPath}'. Verify that the Zune software is not running and try again." );
}
catch ( Exception ex )
{
return Task . FromResult < string? >( ex . Message );
}
2021-04-25 22:59:36 -05:00
}
}
}