Stephen Groom Taking a shot at becoming a Poker Pro

10May/094

Guide: Hackintosh with Asus P5KC

If you read my previous post you will know that this afternoon I have spent a little while (re)installing MacOS on my PC hardware.  The reason is due to a harddrive corruption on the previous install.  I do not place the blame for this on the software I am going to tell you to use, but mostly the choice of drivers that I had installed.  I would warn you off the drivers in question, but I stupidly neglected to take any notes on my last installation.  This time I did not!

Hardware

The hardware I am installing on is as follows:

  • Asus P5KC
  • Intel Q6600
  • 4GB Geil Ram
  • NVidia 8800GTX

Software

There are a few choices for which installer to use when installing MacOS on PC hardware.  The one I chose was iAtkos, mostly because I already had a DVD burned lying around but I'm sure last time there was an educated reason for it.  The following Guide uses iAtkos 5.0i 10.5.5.  I'm not going to offer a download link but if you're creative you should be able to find it pretty easily..

Method

This is not a step-by-step guide.  I am merely typing my notes up into readable form in the hope that it is of to some use to somebody.  For a step-by-step guide or more information about the osx86 project visit their wiki.

So....

The DVD booted without any problems, I loaded the setup, chose Utility > Disk Utility.  I then created a partition and set on my way.

I chose my new partition as the install location and then hit next.  On the next screen I chose Customize and this is where the important stuff is chosen.

I am not going to go into details as to what every option does (mostly because I don't know) but there are descriptions for each on the install disc.

Bootloader:
PC-EFi
X86 Patches:
 - Decrypters
 
Appledecrypt
- Enablers
SmBios Enablers
-Removepowermanagement
-OHR
Drivers:
- VGA
-- Nvidia
NVinject
Efi Strings > 8xxx 
- System
Sata/IDE
NTFS -3G

Once you have chosen these options (or different if you have slightly different hardware), run the installer and let it reboot.  If all has gone well you should be able to Sleep, Shutdown and Reboot.  For my the P5KC onboard lan and sound is missing.  As I don't use onboard sound you'll have to use your initiative.  Lan drivers however can be found here.

I am now installing updates to 10.5.6 and then will quest to re-find my soundcard drivers.  I hope this information is useful to you.

Stephen

P.S.
is it disc or disk?!

Share
Filed under: Software, Tutorials 4 Comments
22Apr/093

Transfer MySQL database to remote server

This post has been rewritten.  Please see How to transfer a MySQL Database to a remote server for updated information

Hey,

This week I've moved back from my ultimate dedi to a Futurehosting VPS in an effort to cut costs and turn a larger profit from Drag Racer.  I tried to make the transfer of data as quick as possible and seeing as how my database is a few hundred MB I transferred it using mysqldump.

First thing's first, you need to prepare the receiving server.  Create a user for the sending server to connect as using this command from the mysql console:

GRANT ALL PRIVILAGES ON *.* TO 'username' @ '  [OLD SERVER IP] ' IDENTIFIED BY 'password';

This will allow your mysql server with the IP [OLD SERVER IP] (replace this with it's real ip ofcourse) to connect using the username 'username' and password 'password'.

Next we are going to use mysqldump in the linux shell (or windows cmd prompt, I'm not 100% where it's located in windows) to dump our databases to our new server.  The syntax of the command is as follows:

# mysqldump -u username -p -h [NEW SERVER IP] [DATABASE NAME(S)]

The command to dump two databases (one called database1, the other database2) to ip 192.168.1.1 is as follows.

# mysqldump -u username -p -h 192.168.l.1 database1 database2

mysqldump will now take a few minutes (depending on the size of the database in question) to dump the entire contents of database1 and database2 onto your new server (in this example 192.168.1.1).  I recommend that once you are finished with this, you remove the user we created to copy the database over.  To do this we use this command from the mysql console:

drop user username;

If you have any questions please leave them below in the comments.  I also recommend using the following website to look up the commands I showed and their uses:
mysql.org

Share
Filed under: Tutorials 3 Comments
14Nov/0823

PHP: Show your facebook status on your blog/website. (Works with new facebook)

Hello

After searching around on the internet for some time, I discovered that all of the previous scripts that had been made to do this job had been written for the old facebook which has long since been depriciated. I then started to consider how I would go about doing this with the NEW facebook since they removed the mini-feed which was vital to the old method.

After some fishing around in google, I resorted to copying links from images in old-method tutorials and stumbled upon this little gem: [url]http://www.facebook.com/minifeed.php[/url]. After trying out the link, and subsequently kicking myself I thought I was onto something. I was jumping for joy as I clicked "[b]Status Stories[/b]" and visited the "[b]Subscribe to these stories[/b]" link, which returned an RSS feed.

I then fired up my php editor, and typed something similar to the following
[php]<?php
$xml=simplexml_load_file(http://www.facebook.com/feeds/status.php?id=820080788&viewer=820080788&key=********&format=rss20);
print_r($xml);
?>[/php]

This returned any amount of horrible errors, and maybe you should try it for yourself to see what I mean. After a few days of poking around, I eventually tried to fetch the same page using my Lynx text-based web browser. What I found was that instead of return XML as it did for me (using IE, Firefox or Safari), a php page was shown with the message:
"You are using an incompatible web browser.

Sorry, we're not cool enough to support your browser. Please keep it
real with one of the following browsers:
* Mozilla Firefox
* Opera
* Safari
* Microsoft Internet Explorer
* Flock"

Now I was onto something :) . If Facebook requires the browser to be Firefox, Opera, Safari, IE or Flock (WTF is flock) then I must have to spoof my way in by pretending to use one of these browsers. Now I had to figure out how I was going to do this. After much trawling of [url=http://www.php.net]php.net[/url] and [url=http://www.google.com]google[/url] I found that there was no way to do it using the method I was previously using. After a few minutes of trying different things, I decided that I was going to fetch the xml file using curl and use the function [i]simplexml_load_file[/i] to load the string instead.

So off I went. Being unfamiliar with Curl, I set about trawling [url=http://www.php.net]php.net[/url] and came up with the following:

All the instructions + explanations are in the php comments (Lines beginning with //)
[php]<?php

// initialize a new curl resource
$ch = curl_init();

// set the url to fetch
curl_setopt($ch, CURLOPT_URL, 'http://www.facebook.com/feeds/status.php?id=[FACEBOOK USER ID]&viewer=[FACEBOOK USER ID]&key=[ACCESS KEY (Get this by visiting this page in your browser from http://www.facebook.com/http://www.facebook.com/minifeed.php#/minifeed.php?filter=11)]&format=rss20');

// don't give me the headers just the content
curl_setopt($ch, CURLOPT_HEADER, 0);

// return the value instead of printing the response to browser
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

// use a user agent to mimic a browser
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20041107 Firefox/1.0');

// execute the curl command
$xml = curl_exec($ch);

//close the connection
curl_close($ch);

//load the result into a simplexml resource
$sxml = simplexml_load_string($xml);

//Get the title (I figured this out by using print_r($sxml)
$title = $sxml->channel->item->title;

//Same for the time
$tmk = $sxml->channel->item->pubDate;

//strtotime returns a integer timestamp which is more useful than our string (yesterday at xxx or whatever it was)
//I also cast to string using (string)$tmk as php was complaining about $tmk being a resource
$timestamp = strtotime((string)$tmk);

//Set the time back to my desired human-readable format
$time = date('d/m/y', $timestamp);

//Italicise my name. You will have to change 11 to the correct length for your name. I get 11 from '<em>Stephen'
//To not italicise your name completely remove this line! \/
$title = substr_replace('<em>'.$title, '</em>', 11, 0);

//Output the result
echo '<p>'.$time.' - '.$title.'</p>';

?>[/php]

And there we have it. If you would like to know more about this script, or I have forgotten something please leave me a comment. I hope this is of some use to you :)

Thanks
Stephen

Share
Filed under: Tutorials 23 Comments
1Oct/0812

JAVASCRIPT: Add BBCode buttons to a form (REVISITED)

From looking at my visitor logs I can see that the clear favourite page on this site is my [url=http://blog.groomi.net/JAVASCRIPT:_Add_BBCode_buttons_to_a_form-,9]BBCODE Buttons[/url] tutorial. After typing a little comment into a blog on here, I realised that the script still is far from perfect and set about improving it.

The problem I had, was that whenever you inserted a piece of bbcode (wherever in the text you did it) the mouse caret (cursor) would always default back to the end of the textarea (A pain in the ass if you're typing something before then).

I then set about making some additions + changes to [i]mybbcode_ins()[/i] function.

What I needed to do was:
1. Find the current cursor position
2. Find the length of the text that I will be inserting
3. Add this to the current position
4. Set the mouse position to the new location.

As always, this was a breeze in Firefox and was acheived by changing the lines

[code]var startPos = field.selectionStart;
var endPos = field.selectionEnd;
field.focus();
field.value = field.value.substring(0, startPos)
+ '[' + tag + '='+url+']' + linkText + '[/' + tag+']'
+ field.value.substring(endPos, field.value.length);
[/code]

to

[code]
var startPos = field.selectionStart;
var endPos = field.selectionEnd;
field.focus();
field.value = field.value.substring(0, startPos) + tag + field.value.substring(endPos, field.value.length);
field.setSelectionRange(endPos+tag.length, endPos+tag.length);
[/code]

I used the smilies section of the code to show the change as this is the easiest to understand. Basically, I have done the 4 steps listed above..

This is all done with the line [i]field.setSelectionRange(endPos+tag.length, endPos+tag.length);[/i] which does step 1 (endPos), step 2 (tag.length), step 3 and 4 (setSelectionRange(endPos+tag.length, endPos+tag.length);)

This however is alot more difficult in IE..

Internet Explorer being as dumb as it is doesn't have a simple way to find the current cursor position. The way it is acheived is by:

1. Making a selection at the current position
2. Moving the selection start to the beginning
3. The cursor location is then the length of your selection
Easy huh?? Not..

What we end up for IE is this

[code]var selected = document.selection.createRange().text;
var ins = tag;
var selected2 = document.selection.createRange();
var sel = document.selection.createRange();
sel.text = tag;
selected2.moveStart ('character', -field.value.length);
sel.moveStart('character', selected2.text.length + ins.length - selected.length);
[/code]
Bloody horrid when compared to the Firefox code, don't you think??

Well. Most of you have probably read the first tutorial and understood that, and are just after the new code.. I give you, [b]bbcode_ins()[/b]

[code]function bbcode_ins(fieldId, tag)
{
field=document.getElementById(fieldId);
if(tag=='b' || tag=='i' || tag=='u' || tag == 'php' || tag == 'code')
{
if (document.selection)
{
field.focus();
var selected = document.selection.createRange().text;
var ins = '[' + tag + ']' + selected + '[/' + tag +']';
var selected2 = document.selection.createRange();
var sel = document.selection.createRange();
selected2.moveStart ('character', -field.value.length);
sel.text = '[' + tag + ']' + selected + '[/' + tag+']';
sel.moveStart('character', selected2.text.length + ins.length - selected.length);

}

//MOZILLA/NETSCAPE/SAFARI support

else if (field.selectionStart || field.selectionStart == 0)
{
var startPos = field.selectionStart;
var endPos = field.selectionEnd;
var selected = field.value.substring(startPos, endPos);
var ins = '[' + tag + ']' + selected + '[/' + tag +']';
field.focus();
field.value = field.value.substring(0, startPos) + ins + field.value.substring(endPos, field.value.length);
field.setSelectionRange(endPos+ins.length, endPos+ins.length-selected.length);
}
}
else if(tag == 'img')
{
var path = prompt('Enter image path', 'http://');
if(!path)
{
return;
}
if (document.selection)
{
field.focus();
var selected = document.selection.createRange().text;
var ins = '[' + tag + ']' + path + '[/' + tag+']';
var selected2 = document.selection.createRange();
var sel = document.selection.createRange();
sel.text = '[' + tag + ']' + path + '[/' + tag+']';
selected2.moveStart ('character', -field.value.length);
sel.moveStart('character', selected2.text.length + ins.length - selected.length);
}
//MOZILLA/NETSCAPE/SAFARI support
else if (field.selectionStart || field.selectionStart == 0)
{
var startPos = field.selectionStart;
var endPos = field.selectionEnd;
var ins = '[' + tag + ']' + path + '[/' + tag+']';
field.focus();
field.value = field.value.substring(0, startPos)
+ ins
+ field.value.substring(endPos, field.value.length);
field.setSelectionRange(endPos+ins.length, endPos+ins.length-selected.length);
}
}
else if(tag == 'url')
{
var url = prompt('Enter link URL', 'http://');
var linkText = prompt('Enter link text', '');
if(!url || !linkText)
{
return;
}
if (document.selection)
{
field.focus();

var selected = document.selection.createRange().text;
var ins = '[' + tag + '='+url+']' + linkText + '[/' + tag+']';
var selected2 = document.selection.createRange();
var sel = document.selection.createRange();
sel.text = '[' + tag + '='+url+']' + linkText + '[/' + tag+']';
selected2.moveStart ('character', -field.value.length);
sel.moveStart('character', selected2.text.length + ins.length - selected.length);

}
//MOZILLA/NETSCAPE/SAFARI support
else if (field.selectionStart || field.selectionStart == 0)
{
var startPos = field.selectionStart;
var endPos = field.selectionEnd;
var ins = '[' + tag + '='+url+']' + linkText + '[/' + tag+']';
field.focus();
field.value = field.value.substring(0, startPos)
+ ins
+ field.value.substring(endPos, field.value.length);
field.setSelectionRange(endPos+ins.length, endPos+ins.length-selected.length);
}
}
else //For smilies
{
if (document.selection)
{
field.focus();

var selected = document.selection.createRange().text;
var ins = tag;
var selected2 = document.selection.createRange();
var sel = document.selection.createRange();
sel.text = tag;
selected2.moveStart ('character', -field.value.length);
sel.moveStart('character', selected2.text.length + ins.length - selected.length);
}

//MOZILLA/NETSCAPE/SAFARI support

else if (field.selectionStart || field.selectionStart == 0)
{
var startPos = field.selectionStart;
var endPos = field.selectionEnd;
field.focus();
field.value = field.value.substring(0, startPos) + tag + field.value.substring(endPos, field.value.length);
field.setSelectionRange(endPos+tag.length, endPos+tag.length);
}
}
}[/code]

I am also considering having the caret sit between the two tags. This will be a simple subtraction of 4 from the length added to the current position.

Please don't be afraid to comment or ask questions below as we have lots of people viewing the site but very few contributing. Please drop me a comment telling me wether you hate me, appreciated my code, want to hire me for work :wave: etc etc. I don't bite, and will probably write some new code if I see that mine is being appreciated :)

Much Love
Stephen

Share
Filed under: Tutorials 12 Comments
14Aug/080

Secure login form with AJAX, Javascript + PHP

Hello, It has been quite a while since I posted a tutorial on this website and I have noticed that my Javascript/AJAX tutorials are in quite high demand. In between developing some other sites, I remembered how interesting it was coding my admin panel's secure AJAX login and how little documentation there was about such a method on the internet.

[b]The theory[/b]
The page I was protecting was to be accessed by me only and was to display a login prompt to all users attempting to access it. The form would then be filled in and the data would be sent to my PHP script. The PHP script would then need to decide wether or not the user's credentials are correct and either display the page requested or refuse the user access. The problem that I faced was that it was very difficult to create a javascript function that would do all this while remaining secure. I think my method is hack-proof but I will soon find out when this source code is read by the public, so here goes!

[b]How it's done[/b]
The first thing we will need is a HTML login form, but not a normal login form. This one will contain an [i]onSubmit[/i] attribute containing our javascript function call. Here is the form we will be using:

[code]<div id="content">
<form action="javascript:void(0);" onsubmit="login(document.getElementById('user').value,document.getElementById('pass').value);">
<p>
Username<br /><input id="user" type="text" /><br />
Password<br /><input id="pass" type="password" />
<input id="submitpop" type="submit" value="" />
</p>
</form>
</div>
[/code]

The action attribute is set to call [i]javascript:void(0);[/i] which simply ensures that the form does not post the data conventionally. The onSubmit attibute calls our javascript function, which will be used to authorise the user. We use [i]document.getElementById('input_id').value[/i] to send the values of the user and pass text inputs to our javascript.

Next, we need to create the javascript function [i]login[/i].

[code]function createhandler(){
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}
else if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
return xmlhttp;
}

function login(user,pass)
{
var content=document.getElementById('content');
var xmlhttp=createhandler();
var params='user='+user+'&pass='+pass;
xmlhttp.open('POST', '/login.php', true);
xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xmlhttp.setRequestHeader('Content-length', params.length);
xmlhttp.setRequestHeader('Connection', 'close');
xmlhttp.onreadystatechange=function()
{
if(xmlhttp.readyState==4){
if(xmlhttp.responseText!=0)
{
xmlhttp.open('POST', '/loggedin.php', true);
xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xmlhttp.setRequestHeader('Content-length', params.length);
xmlhttp.setRequestHeader('Connection', 'close');
xmlhttp.onreadystatechange=function()
{
if(xmlhttp.readyState==4)
{
content.innerHTML=xmlhttp.responseText;
}
};
xmlhttp.send(params);

}
else
{
alert("Failled Login");
}
}
};
xmlhttp.send(params);
}[/code]

The [i]login[/i] function starts by calling [i]createhandler[/i]. This returns our ajax [i]XmlHttpRequest[/i] object. The function then posts our username and password to login.php. If login.php returns a value other than '0' then loggedin.php is loaded with the same user and password as login.php, this extra step probably isn't really necessary but it was the way I coded the function for my purpose. It may be just as easy to put your content inside login.php, but for some reason I didn't. If 0 is returned, then an alert box is called with the text "Failled Login" and no further action is taken.

That is it for the HTML and Javascript. The next step is our php file(s) which determine wether or not a correct username + password has been entered. For my script I used a username and password stored in a MySQL database but for ours we are going to set the correct values within the script.

[b]login.php[/b]
[php] $user='username'; //Our username
$pass='password'; //Our password

if($user==$_POST['user'] && $pass==$_POST['pass'])
echo 1;
else
echo 'Failled Login';
?>[/php]

This PHP script checks if the username submitted is [i]username[/i] and the password is [i]password[/i]. If the combination is correct, it displays 1, 0 if it is incorrect.

[b]loggedin.php[/b]
[php] $user='username'; //Our username
$pass='password'; //Our password

if($user!=$_POST['user'] || $pass!=$_POST['pass'])
return;

echo'Anything below the return; statement will be displayed only if the correct password is entered. There is no need for an error message as this page should only be accessed by a javascript hack attempt or correct password :-) ';
?>[/php]

The page will return blank if it is not given the correct username and password. If it is, the page is displayed. If you want a user to be logged in without having to enter his details again, it is a good idea to store his username + password in a session or cookie. If you are reading this tutorial though, I would assume you already know how to do this. If you want information about how to implement sessions or cookies into this script, please leave a comment below and I will write another tutorial.

Peace
Stephen

[b]PS.[/b] I would love for someone to try to hack the system on this site so please do, this code is implemented as written on my admin login available if you right-click. I would love to hear any weaknesses the code has so feel free to try :D

Share
Filed under: Tutorials No Comments