Sunday 13 December 2015

Electronic Arts have the worst support portal EVER!

I'm incredulous at EA's very bad support process.

I had purchased some in-app content for my son's tablet, and after an app reinstall it would not resume the content.

So I tried, repeat, tried to contact EA.

Their Contact Us portal is horrific. It is a "fake" contact us, wherein it pretends to offer you an ability to contact but in reality forces you down the check forums and raise a ticket via the portal.

But the portal was horrific.

Trying to raise a new ticket on this URL didn't work.
1. Go to https://help.ea.com/en/fifa/ea-sports-fifa/
2. Scroll down and select "Contact Us"
3. Click on Android Tablet and select Next
4. Select "Missing Content" and "Had content and lost it"
5. In the "Please tell us a little more about your issue" box type "In-App Purchases"
6. Press Next
7. You get dumped on Step 3 above. You cannot complete the support request.

Eventually I chose a different selection option and got to the end screen. But if I attached a PNG to the ticket whilst raising it - it dumped you back at the beginning.

Eventually I figured I had to raise a ticket under the wrong option and submit it. And then attach the JPG after.

During this process I was in an email conversation with a support guy who was adamant I should attach the PNG to a support ticket that he had raised of which I had no access to.

In all, this whole debacle cost me 1.5 hours of my life, to fix a problem with my son's in app purchase. It is enough to put me off in-app purchases for life!

NB: I contacted Google and they refunded it within 5 minutes. They've got the right customer experience.

Monday 7 December 2015

Port exhaustion on Windows server

We had a set of servers that started showing what seemed to be random connection errors. They ran across services and across servers.

Our first thought was it was a hardware or centralised switch problem, but the network guys assured us the switch had no problem.

Then we started leaning towards configuration problems on the boxes. These servers ran multiple services, all heavy socket consumers.

Whenever a socket connection is made to a known port, Windows also uses a temporary socket for the return communications. These temporary sockets, known as ephemeral or short-lived sockets, are assigned from a pool which can be configured.

netsh int ipv4 show dynamicportrange tcp
Protocol tcp Dynamic Port Range
---------------------------------
Start Port      : 50001
Number of Ports : 255

This is an incredibly low number for a server high in comms. It shows that when a socket is created, only 255 are available. Bearing in mind when the communication has completed the socket remains open for a short while (known as the TcpTimedWaitDelay) for efficiency in reuse. This defaults to 30 seconds.

Also the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters showed  a MaxUserPort of 1279, which conflicted with the StartPort + Number of Ports range.

In a state of port exhaustion MS documentation says that you can get non-specific errors that just look like general connection errors.

e.g.
System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send.

References
https://msdn.microsoft.com/en-us/library/aa560610(v=bts.20).aspx
http://www.outsystems.com/forums/discussion/6956/how-to-tune-the-tcp-ip-stack-for-high-volume-of-web-requests/
https://technet.microsoft.com/en-us/library/cc938219.aspx

Sunday 6 December 2015

Installing gpiozero on the Raspberry Pi (Wheezy)

I found it troublesome to install the gpiozero package in order to interface to the Rasbperry PI IO.

In the end the following commands worked:

sudo apt-get update
sudo apt-get install python3-pip

sudo pip-3.2 install gpiozero

Test it with
sudo python3 -c "import gpiozero"

https://docs.google.com/document/d/1EbbVjdgXbKVPFlgH_pEEtPZ0zOZVSPHT4sQNW88Am7w/edit?pli=1#

Running the program within IDLE raised the exception about not able to access /dev/mem. To fix this I added the IDLE shortcut to the desktop, ran the nano editor under sudo to edit the shortcut and ran IDLE with the sudo prefix.

Tuesday 24 November 2015

Fakes Mocks and Stubs

Fakes, Mocks and Stubs offer varying depth of business logic.

A Fake is a simple object that contains no business logic. It simply contains specific values (such as good or bad) that can be injected into a test to determine the result.

A Mock allows the test to replace a method call or property accessors to return a particular value. For example the test can mock a repository class to return pre-canned data when the Read() method is called. Mocks are also useful in unit tests as they can tested that particular methods were called and how many times they were called. You can assert against a mock.

A Stub is more comprehensive and at the coding level can replace an entire class. For the repository example the repository could be replaced with a StubRepository and this either returns a response based upon input data or based upon some preconfigured data.

Beyond the coding level a Stub can also be used to replace a subsystem. If a payments system is calling a third party interface, it may be necessary to stub out the 3rd party. This benefits if calling the third party costs money, if performance tests are required, if you want to avoid overloading the third party, or if the third party is unable to provide the failure scenarios when you need them.

For a stubbed interface it is often useful to return output data based upon input data. For a Fraud-checking stub, the response may vary based upon the applicant's last name, e.g. fail fraud checks if the last name is "MyLastName_Fail". You want to avoid statefulness in the stub or vary the response from the stub based upon configuration, which would require a system restart.

For performance testing it may also be useful to simulate latency based upon input data. In our Fraud Check example the response may delayed by 5 seconds if the applicant's first name was "MyFirstName_5s". This delay may help tease out scalability problems or race conditions in neighbouring parts of the system. The test driver can then issue a variety of load conditions simply by supplying varying usernames as request parameters.

Tuesday 3 November 2015

I found my AD account being locked continuously when I had an enforced password change. This was because I had many disconnected (but not logged off) RDP sessions on many test servers across the network. So with the help of this PowerShell module, I wrote a script to detect which sessions were left open so I could manually log off.

Import-Module PSTerminalServices

$username = 'AndrewPotts'
$servers = @("serverA","serverB")

foreach ($server in $servers)
{
 Write-Host -NoNewLine $server
 
 try
 {
  $loggedOn = $False
  
  Get-TSSession -ComputerName $server | ForEach-Object { 
   if ($_.Username -eq $username) { $loggedOn = $True }
  }
  
  
  if ($loggedOn -eq $True)
  {
   Write-Host -ForegroundColor Yellow ' Logged on'
  }
  else
  {
   Write-Host
  }
 }
 catch [System.Exception]
 {
  Write-Host -ForegroundColor Red ' $_.Exception.Message'
 }
}

Debugging with WinDbg

Open a command prompt as administrator.


If you get
Cannot load "xxx"

when typing
.load clr sos

then make open a command prompt as administrator

set the path to include the .net framework 2.0 and 4.0

C:\windows\Microsoft.NET\Framework\v4.0.30319\

If it is a 32-bit process, load the 32-bit windbg and reference
the paths to the 32-bit .NET

If it is a 64-bit process, load the 32-bit windbg and reference
the paths to the 64-bit .NET, eg:
C:\windows\Microsoft.NET\Framework64\v4.0.30319\

WCF scalability settings

This article provides a good steer on the scalability settings for WCF.

IIS and Impersonation

Setting
<authentication mode="Windows" />
<identity impersonate="true"/>

on an IIS application will set the thead to run under the identity of the current user. All calls, such as file writing, writing to the event logs, will run under the identity of the current authenticated user. In this case you need to ensure that the folders and event logs allow the current user (indeed all potential users that may authenticate) to perform the task.

Note also, that if you want to pass on those credentials, for example to call another webservice or Website that requires Windows Authentication, then you need to enable delegation. By default the first Website is only allowed to impersonate, but not pass on the credentials to a 3rd party. To allow this you need to configure delegation for the Website in Active Directory. You also need to ensure the client can authenticate using Kerberos (this may involve setting the trust levels for the URL).



However, I found running the application under the context of the user at all times is troublesome. For example, Log4net fails to write to a network share, despite me setting Everyone=Full Permission.

It is probably far better to allow the Web application to run under the service account as normal, but impersonate the user only for the short call to the back-end Web service.

To do this, set
<authentication mode="Windows" />
<identity impersonate="false"/>

this ensures the application runs under the service account. Then write the code to impersonate the user.

var windowsId = (WindowsIdentity)User.Identity;
            WindowsImpersonationContext windowsContext = null;

            try
            {
                // Start impersonating
                // http://msdn.microsoft.com/en-us/library/ff647404.aspx
                windowsContext = windowsId.Impersonate();

                result = service.ValidateTrades(trades);
            }
            catch (Exception error)
            {
            }
            finally
            {
                // Revert impersonation
                if (windowsContext != null)
                {
                    windowsContext.Undo();
                }                
            }

Dell Inspiron 7537 versus the HP Touchsmart 15-j105sa

I've received both the Dell Inspiron 7537 and the HP Touchsmart 15-j105sa.

Here are my initial views on them:

HP Touchsmart 15-j105sa

Positives
It looks sturdier.
In my opinion it looks more attactive.
It outperforms the Dell in CPU performance.
The battery is removable.

Negatives
The glass is more reflective; you can see yourself in the screen.

 Dell Inspiron 7537

Positives
It outperforms the HP in the high end graphics place.

Negatives
It has a RJ45 network connector with a hinged cover. This is sure to be a pain and break in the future.

There are reports of an underperforming WIFI adapter (which may now be resolved).

The battery and memory are contained within the back which you have to unscrew to get access to.

Verdict
I actually prefer the HP Touchsmart, yet the better NVidia 750M on the Dell is enough to sway it for me.

Decimal layout

I've just had a few hours debugging decimals.

decimal x1 = 256m;
decimal.GetBits(x1).Dump();
Console.WriteLine(string.Format("{0}", x1));


decimal x2 = 256m * 1.0m;
decimal.GetBits(x2).Dump();
Console.WriteLine(string.Format("{0}", x2));


http://msdn.microsoft.com/en-us/library/system.decimal.getbits(v=vs.110).aspx

Reverse Engineering Android Apps

Launch Web PC Suite
Select Apps
Select the App and select Backup
The APK is copied to SDCard\Tablet\BackupApps
Copy the APK to the local computer
At a command prompt type apktool d <apkfile.apk>

or

 Rename your APK file(e.g., rename your APK file to .zip Ex- test.apk -> test.zip) & extract resultant zip file.
Copy your .dex file in to dex2jar folder.
Run setclasspath.bat. This should be run because this data is used in the next step.
Go to Windows Command prompt, change the folder path to the path of your dex2jar folder and run the command as follows: d2j-dex2jar.bat classes.dex
Open the jar file in JD GUI.

Reformatting MPEG-2 DVD to another format

VirtualDubMod is useful for converting MPEG2 TS files to another format.

NServiceBus, DTC and MSMQ

I've spent the last week performance testing our NServiceBus solution extensively.

Our first implementation used MSDTC.
During performance testing of an NServiceBus application using MSMQ transport, we managed to kill MSDTC many times. It would go into a period of hanging for 20 minutes and everything around it; including endpoints not owned by us, stopped working.

We turned off enlistment of the databases called by the handlers by altering the connection strings. This still didn't stop MSDTC from hanging.

Analysis of the stack traces showed that NServiceBus was still engaging MSDTC through the use of TransactionScope around the handler. Although we have switched DisableDistributedTransactions = On, the handlers were still using the local transaction coordinator. We had to set DoNotWrapHandlersExecutionInATransactionScope = true.

The different settings are:
1) DisableDistributedTransactions = off, DoNotWrapHandlersExecutionInATransactionScope = off . The entire handler will be wrapped in an outer transaction scope. Any Bus.Sends will not be immediate and will wait till the outer transaction scope completes. In case of a rollback of the outer transaction scope all the Bus.Sends will be rolled back as well as any database work enlisted in the transaction scope will roll back.

2) DisableDistributedTransactions = on, DoNotWrapHandlersExecutionInATransactionScope = off. The entire handler will be wrapped in an outer transaction scope. Any Bus.Sends will be immediate and will not participate in the outer transaction scope. In the case of a rollback of the outer transaction scope the bus.sends will not roll back but any database work in the handler will roll back.
3) DisableDistributedTransactions = off, DoNotWrapHandlersExecutionInATransactionScope = on. The handler will not be wrapped in an outer transaction scope. I will explicitly have to start a transaction scope and any bus.sends will not be immediate (they completed upon outer transaction scope complete) and database work done within the manually started one will rollback together. Anything outside of my manually created transaction scope will not rollback.

4) DisableDistributedTransactions = on, DoNotWrapHandlersExecutionInATransactionScope = on. The handler will not be wrapped in an outer transaction scope. Each bus.send will be within its own transaction and if a transaction scope is created manually by me those bus sends will not enlist in it will execute immediately and will not roll back if the outer transaction scope rolls back. Any db work done within the manual transaction scope will roll back.

https://groups.google.com/forum/#!msg/particularsoftware/SoxeC4RwLlg/Kdt-gjTXYEIJ

Having changed this we were now using TransportTransactions. MSMQ still can handle a Receive and send in a transaction, without using DTC.













MSMQ uses memory-mapped files to store messages (regardless of whether they are express, recoverable, durable). It uses a 4MB file for every message and cleans them up every 6 hours. If you see the memory go very high you can initiate the cleanup by running the following PowerShell:

$MyMSMQApp = new-object  –comObject  MSMQ.MSMQApplication
$MyMSMQApp.Tidy()

NServiceBus and MSMQ Transport Transactions

If Distributed Transactions and ambient transactions are turned off, then you are reliant upon MSMQ transactions.
On a transactional queue and with the appropriate code then the Receive operation on the queue will be transactional. This allows NSB to take a message off a queue - preventing other handlers from reading it - process it and if it fails put it back on the queue.
However the MSMQ transaction will only group Receives together in a transaction, or Sends, not a mixture.
So if you have code like this:

a. Begin MSMQ transaction
b. Read Message
c. Process Message
d. Send Result Message onwards
e. Commit Transaction

then this is fine if the point D is the last action in the transaction. If anything fails before it, the MSMQ transaction will fail and the original message at B will be put on the input queue. No output message will have been sent as the processing before it will have failed.

However if you have more than one output message it will yield bad results. Take this scenario:

a. Begin MSMQ transaction
b. Read Message
c. Process some of the message
d. Send Intermediary Message onwards
e. Process some more
f. Send Result Message onwards
g. Commit Transaction

If step E fails then the transaction will be rolled back and the message at B returned to the input queue. However the MSMQ transaction will not roll back step D - the intermediary message will be sent despite the failure of the transaction.

Saturday 22 August 2015

Default IIS permissions

IIS 6.0 (Windows 2003)
IIS Worker ProcessUnauthenticated access writes files as
InetInfo.exe (SYSTEM)w3wp.exe (NETWORK SERVICE)Internet Guest Account (machinename\IUSR_machinename)

Saturday 11 July 2015

Putting the native32 games on an SD-card for the Xtrons Headrests

I used a 8GB Micro SD Card and formatted it to FAT32.

Go to the native32.com Web site. Click on the Game Lib tab and click on the Batch Download link.
This downloads AllGame070927.rar. Use 7-Zip (an Open Source compression tool) to expand this rar file and copy all the contents to the root of the SD card.

You then have to download the Flash UI (note this doesn't flash your ROM - this means flash as in 'snazzy'!). Click on the Home Tab and click on the Flash UI link. Again, using 7-zip, expand the compressed file and copy fhui.smf to the root of your SD card. This fhui provides a menu for the games. Without this they don't appear to work correctly!

Doing this enables you to play games without having to keep a CD in the unit. You can also put movies in the root too - just make sure they're the correct format.

Video encoding for the Xtrons HD905 headrests

To play movies on the Xtrons HD905 headrests:

Download TEncoder from SourceForge.

Settings : AVI container
-  Video : Codec XVID, Bitrate 1024 kbps,
               Size 720x480 px with 'Force aspect ratio' to prevent stretched heads
               FPS same as Source
-  Audio : MP3, max 320 kbps.
AAC audio definitely does not work. AC3 only works on some AVI's.

Saturday 13 June 2015

Single payment, multiple invoices in Kashflow

Sometimes you will invoice a client multiple times and they will make one payment.
I find this very hard to manage in Kashflow so I have recorded the process.

In the bank statement, select the bulk payment and Assign to Invoice, choosing one of the invoices.

Then go to the other invoice(s) and select Apply Credit.
It will allow you to select which Advance Payment (overpayment) you have made.

Monday 8 June 2015

Disconnected RDP session causes AD account lockout if password changed

I had a RDP session to a remote machine and I disconnected from it - I didn't logout.

At some point later I had to change my AD password as the expiry policy required.

However thereafter I kept getting logged out at regular intervals. In the end after some AD diagnosis it was found that it was this disconnected session. After properly logging out the problem went away.

"Remote Desktop Services Manager" is part of Windows 7 and can be used to list which computers are logged into. This can be added if it is not already from Control Panel > Turn Windows Features On or Off > Remote Server Admin

Wednesday 6 May 2015

Citrix Access Gateway crashes on startup

Recently Citrix Access Gateway has started crashing on startup when I work from home.

Steps to resolve:

Uninstall
Download a newer version
Run the VPN client using Firefox
It will then ask to downgrade
Then it works

Thursday 30 April 2015

Visio hidden gems

Curved connectors

To add a curve point, select the line, then select the Freeform tool (the fourth Tool, CTRL+T, normally defaults to Rectangle), hold down the CTRL key and place a point on the line.

To remove a curve point, select the line with the pointer tool. Click on the point and it will turn red. Press the delete button.

Adding Connection Points to shapes

Select the shape first. Make sure the correct shape is selected otherwise you will add the point to the wrong shape and it will probably be floating with an offset. Select the Connection Point Tool (CTRL+SHIFT+1). Hold down the CTRL key and press the left mouse button where you want the point to appear.

Monday 27 April 2015

Code Analysis CA1704: Identifiers should be spelled correctly

I had a variable, DisableDtc, that was throwing code analysis error

CA1704: Identifiers should be spelled correctly.

The description is slightly confusing. What it really means is that it doesn't think one of the words is a real word.

In this case, it recognises Disable, but doesn't recognise Dtc.
The solution is to add Dtc to Dictionary/Words/Recognised/Word.

Saturday 11 April 2015

Betting Online - what they DON'T tell you

It's the annual Grand National and a chance for the family to engage in a very gently competitive and fun event: choose a horse and put a pound on it to win and a pound each-way. So we put down quite a lot of £1 bets.

And you might win a small amount; a few quid.

This year we did.

So we logged in to Paddy Power to collect our £5. But hold on, no; it's £4. Apparently there is a Rule 4, which enables the bookmaker to reduce the winnings by a percentage because a horse pulled out.

But hold on - the horse that pulled out, Carlito Brigante, pulled out YESTERDAY. And we live in a modern gambling world with in-play gambling where they can alter the odds during a game. Where if Ronaldo scores the next penalty the odds are constantly updated. So surely they could have altered the odds accordingly 2 hours before the race, 5 minutes before, 30 seconds before?

No, it's in the small print.

So OK, it's £4 then. Can we have it?

No, apparently not. There are minimum withdrawal limits. £10 please.

So you either have to put down a bigger stake, or perhaps you would like to bet with us again sir?

When I asked, I was told

"The limits and terms are all on site for customers to check before depositing if they wish."

and

"We have a search function within the help centre"

All very correct, but not very benevolent. So I'd better read the T&C's then. I copied them into Microsoft Word. They were 27 pages and 13,236 words.

Do companies really expect us to read all of that before engaging in an activity? I'm sure there are more words there than my household insurance.

With all that tech at their finger tips and all their advertising might, Paddy Power don't make it clear that the small £1 bet is meaningless.

The morale of the story? Small bets suck. Paddy Power don't help. Stay away from a mugs game.

Saturday 4 April 2015

Stock Messaging App keeps crashing on Android - Samsung Galaxy S3 mini

On a friend's Samsung Galaxy S3 Mini when I went into the stock Messaging app, it would pause on a black screen, and then crash with the error dialog.

Some research suggested going into Settings > Application Manager and swiping right until "All" is selected at the top. Select messaging and then "Clear Data" and "Clear Cache".

Unfortunately this didn't work.

I then rebooted the device into Safe Mode. This required turning the device off, turning it back on and holding the Volume Down button when the Samsung logo was displayed.

I then went  into Settings > Application Manager and selected Log Provider (it was at the bottom). It said "Disabled" against it. I clicked it, enabled it, and then the messages app started working again.

I noticed by debugging the app there was an error "Failed to find provider info for logs". Also "Process com.android.mms (pid xxxx) has died."

Tuesday 31 March 2015

Android Concurrent Programming

Here is a short summary of available options for concurrent programming in Android

AsyncTask<> - useful for a short-lived task that has UI interactivity. The work is done in the doInBackground method, and there are methods for pre and post-task that will execute on the UI thread. This option should not be used for long running operations lasting more than a few seconds as it could be terminated by the system.

Background threads - Manually created. You can choose between an explicitly created thread and one from a thread pool. A background thread may still be terminated by the operating system before it finishes. Useful for operations from 100ms up to a few seconds.
The thread class has to be passed an implementation of the Runnable interface and Thread.Start is called.

Future - a representation of a value that has not yet been computed. The example below creates a future and starts the work. Other tasks are performed in the background. However the calling thread is then blocked as the future's get method is called and the caller awaits the result. (Of course the result may already be available at this point and so the caller is not blocked in this situation).

Future future = executor.submit(new Callable() {
         public String call() {
             return searcher.search(target);
         }});

displayOtherThings(); // do other things while searching

try {
       displayText(future.get()); // use future (will block the caller)
}
catch (ExecutionException ex) { 
       cleanup(); 
       return; 
}


FutureTask - an implementation of a future. It implements the Runnable interface and so may be executed by an executor.

FutureTask future = new FutureTask(new Callable() {
     public String call() {
       return searcher.search(target);
   });
 executor.execute(future);}
 
Some useful slides detailing a lot more techniques are here.

Saturday 21 March 2015

Recording video

Fraps is good for recording in-game video. To transcode it to something more suitable for YouTube, use Handbrake.

Tuesday 24 February 2015

Returning custom error JSON in a Web API

Often when a Web API fails you want to return more than a HTTP status code and a string. Like a full JSON object. Yet you don't want to corrupt your original return type for normal flow.
These articles describe how you can return a different type for error scenarios:

http://blog.codeishard.net/2013/02/09/webapi-and-the-behavior-of-exceptions-and-an-alternative-configurable-way-to-deal/

http://stackoverflow.com/questions/16243021/return-custom-error-objects-in-web-api

Monday 23 February 2015

Creating GUIDs (UUIDs) in Javascript

With the advance of distributed systems, there is a growing need to generate unique identifiers on the client.

There are several versions of GUID algorithms. .NET ultimately wraps the CoCreateGuid function. Windows originally started with an algorithm using the machine's MAC address, but now it uses version 4 UUIDs. You can tell this because they have the form:

xxxxxxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxx

Although the chance of a conflict is remote in the extreme, it is good practice to use the same version scheme on both client on server. Broofa creates RFC-compliant GUIDs (both version 1 and version 4) in JavaScript. Use version 4 for uniformity with Server-side Windows.

Saturday 21 February 2015

Minecraft Forge 1.7.2 stopped working

Minecraft Forge 1.7.2 stopped working with a new Java update. Fortunately this post details how to fix it.

I quote:

"
So you may have heard that as of Java 8 update 20, a bug came to light in Forge which causes a crash at startup. This appears to affect both Minecraft 1.6 and 1.7. Fortunately, later versions of Forge for 1.7.10 correct the issue. But 1.6.4 and 1.7.2 are still affected, as are many versions for 1.7.10 still in use. You could easily just use Java 7, or Java 8 update 11, and not be affected by this bug. But for future-proofing sake, in case someone wants to run Java 8 but a security issue is discovered at some point in the future which makes update 11 not very safe, I decided to just fix Forge.

Only one file is the problem, so that's all you need:

CoreModManager.class, for Forge #965 for Minecraft 1.6.4.
or
CoreModManager.class, for Forge #1121 / #1147 for Minecraft 1.7.2
or
CoreModManager.class, for Forge #1208 for Minecraft 1.7.10

-- Vanilla --

I'm going to assume you already have Forge installed into the vanilla launcher for these instructions.

From here you need to find your way into your libraries directory for Forge. On Windows, the direct route would be:

For 1.6.4: %appdata%\.minecraft\libraries\net\minecraftforge\minecraftforge\9.11.1.965

For 1.7.2: %appdata%\.minecraft\libraries\net\minecraftforge\forge\1.7.2-10.12.2.1147 (or switch 1147 for the version you're using)

For 1.7.10: %appdata%\.minecraft\libraries\net\minecraftforge\forge\1.7.10-10.13.0.1208

If you use Linux then you know your way around your home directory. And if you use OSX, then I'm sure someone else can help you find it, but I imagine that your base Minecraft directory is in your home directory somewhere as well like Linux.

You can make a backup of the JAR if you want at this point. But now open up the JAR in WinRAR or what ever program you use for such things. First, go ahead and delete the META-INF directory in the root of the JAR, or you'll get a crash related to security, just like in the old JAR-modding days. Now navigate your way through cpw/mods/fml/relauncher. You should see a CoreModManager.class in here. Just drop this patched version on top, and you should be good to go!


-- FTB --

This is relatively identical to the above instructions. The only difference is that you have to find the libraries directory inside your FTB directory instead. Then do the same process as above, and this should fix every related pack on the launcher.

-- Technic --

This is a bit different. You need to patch individual modpacks. And every time a pack is updated, you'll probably have to patch it again. But it's not a big deal. For this, first go into your packs directory. For Windows this is: %appdata%\.technic\modpacks

Now go into whichever pack you want to fix. For this example we'll use the main Tekkit. So navigate into tekkitmain, then into bin. You should see a modpack.jar here. This is basically your Forge JAR. Follow the process of above for patching the JAR, of deleting META-INF and adding the class file into the appropriate place, and your pack should now run again.

-- ATLauncher --

Again, this is slightly different, requiring you to fix per-instance like Technic. Go to your ATLauncher directory, then into instances. Find the instance you want to repair, then go into jarmods. You should see the Forge JAR here. So do the above mentioned process to patch the JAR, and the pack should be fixed. Like Technic, updates might break it.

-- MultiMC -- 

I have no easy fix for this at this time, because it automatically redownloads the Forge JAR after it detects modification, which is both nice and annoying depending on the situation!


-- Servers --

In this case, Forge will already be in the server JAR. You won't want to erase all of META-INF or the server won't launch, just deleting FORGE.DSA is enough according to DAOWAce's post below. Then just copy the class file you downloaded into the appropriate place in the JAR.



-- Misc --

Now for the technical details of what this does, for those interested. Java 8 update 20 changed the way Collections.sort works, no longer cloning a List but modifying it in-place. Since FML is iterating this list at this particular moment, you get the crash. So what this patch does is replace Collections.sort with a wrapper function inside CoreModManager.

It does this:

public static <T> void sort(List<T> list, Comparator<? super T> c)
{
T[] toSort = list.toArray((T[])new Object[list.size()]);
Arrays.sort(toSort, c);
for (int j = 0; j < toSort.length; j++) list.set(j, toSort[j]);


This is basically a modified version of the same code used to fix later versions of FML, just implemented differently for the sake of a patch.

What I did was compile this bit of code in an otherwise empty class, then used Java Bytecode Editor to extract the bytecode from that class and create the identical method in CoreModManager. Lastly I modified the sortTweakList method to invoke cpw/mods/fml/relauncher/CoreModManager/sort instead of java/util/Collections/sort. You can use JBE to confirm youself that that's the only difference between this patched file and the original if you're concerned at all.

There's a chance that the 1.6.4 patch will work on other versions of Forge for 1.6.x, you would just have to try it and see. The two 1.7.2 builds are the 'latest' and 'recommended' ones, and both had an identical version of CoreModManager, though it might work on earlier builds for that version as well if necessary.

Hope this helps!
"

Friday 6 February 2015

SQL for showing outstanding replication commands

The collection of T-SQL below helps identify outstanding replication commands
use distribution
go
select * from dbo.MSarticles
where article_id IN (SELECT Article_id from MSrepl_commands
where xact_seqno = 0x0002E17600000131000600000000)

sp_browsereplcmds @xact_seqno_end = '0x0002E17600000131000600000000'
sp_browsereplcmds @xact_seqno_start = '0x0002E17600000131000600000000', @xact_seqno_end = '0x0002E17600000131000600000000', @Command_id = 1, @publisher_database_id = 1

select * FROM MSArticles a where article in ('DiscountCode', 'DiscountCodeCountry', 'DiscountRule')
select * from M

-- Discount Code
sp_browsereplcmds @article_id = 60, @xact_seqno_end = '0x0002E17600000131000600000000'
sp_browsereplcmds @article_id = 61, @xact_seqno_end = '0x0002E17600000131000600000000'
sp_browsereplcmds @article_id = 62, @xact_seqno_end = '0x0002E17600000131000600000000'

EXECUTE sp_replmonitorsubscriptionpendingcmds 
@publisher ='.\PublisherDb', -- Put publisher server name here
@publisher_db = 'MyPubDb', -- Put publisher database name here
@publication ='Discount-Publication',  -- Put publication name here
@subscriber ='.\SubscriberDb', -- Put subscriber server name here
@subscriber_db ='MySubDb', -- Put subscriber database name here
@subscription_type ='0' -- 0 = push and 1 = pull
The SQL below shows the replication performance for a table.

use distribution
go

select min(dh.delivery_latency) min, avg(dh.delivery_latency) avg, MAX(dh.delivery_latency) max
from MSarticles a 
inner join MSpublications (nolock) p on a.publication_id = p.publication_id
inner join MSsubscriptions (nolock) s ON p.publication_id = s.publication_id and s.article_id = a.article_id
inner join master..sysservers (nolock) ss ON s.subscriber_id = ss.srvid 
inner join master..sysservers (nolock) srv ON srv.srvid = p.publisher_id 
inner join MSdistribution_agents (nolock) da ON da.publisher_id = p.publisher_id  AND da.subscriber_id = s.subscriber_id and da.publication = p.publication
inner join distribution.dbo.MSdistribution_history (nolock) dh on dh.agent_id = da.id
where a.destination_object = 'MyTable'
and s.subscriber_db = 'MyDB'

Find out the replication properties of a table

The script below lists the publisher, subscriber and publication for a replicated table in SQL Server. It is executed against the distribution database.

use distribution
go

-- View the replication properties of a table
select a.publisher_db, s.subscriber_db, a.article, p.publication, p.publication_type
from MSarticles a 
inner join MSpublications p on a.publication_id = p.publication_id
inner join MSsubscriptions s ON p.publication_id = s.publication_id and s.article_id = a.article_id
inner join master..sysservers ss ON s.subscriber_id = ss.srvid 
inner join master..sysservers srv ON srv.srvid = p.publisher_id 
inner join MSdistribution_agents da ON da.publisher_id = p.publisher_id  AND da.subscriber_id = s.subscriber_id and da.publication = p.publication
where a.destination_object like '%discountusage%'

Testing a REST API with Powershell

With the following Powershell script, you can issue a POST request to a REST endpoint

add-type @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
        }
    }
"@

[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

$uri = 'https://myurl.com/v1/MyResource?param=true'

$body = 
'{
    "products": [
        {
            "productId": 1,
            "quantity": 0
        },
        {
            "productId": 2,
            "quantity": 0
        }
    ]
}'


$response = Invoke-WebRequest -Uri $uri -Method POST -Body $body -ContentType 'application/json; charset=utf-8' 
$response.Headers