Thorough instant message system V0.9 [UPDATED to work]

Pages: 1, 2
free web hosting

Read Latest Entries..: (Post #11) by welbis on Jan 18 2005, 01:47 AM. (Line Breaks Removed)
Yeah it works a bit like PMs, but when you get a new one it prints a little box at the top of the screen above the content for 2 minutes after its sent. If you want a demo, then go to my site, register, and send yourself a PM. If you dont want me to send you an email when i've finished my site then put 'delete me' in the info field when you sign up.... read more.
Read the FIRST post of this Topic. - Express your Opinion! Contribute Knowledge :-).

Open Discussion > Have your say > General Talk

Thorough instant message system V0.9 [UPDATED to work]

welbis
I have made an instant message system which is quite complicated. To implement this you may need a reasonable knowledge of php, you will also need a login system that has parsed the username to a variable $username. For this specific example to work best you also need to be able to assign $user_level to a value more than 2 if an admin is logged in.

MYSQL tables are at the bottom.

FIRST. Create a file, name it formtemplates.php and give it the following content.

If you use this, Please link back to my site at
www.jesus-freaks.co.uk, as this system took me a lot of time to make

CODE




<?

if(isset($_SESSION['username'])) {

$username = $_SESSION['username'];

} else {

$username = Guest;

}

$user = $_GET['user'];





$priv_query = mysql_query("SELECT * FROM users WHERE username='$user'");

$priv_num = mysql_num_rows($priv_query);



if($priv_num == 1) {



$value = "value="1" CHECKED";

}



$send_message = <<<HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">



<form action="?page=message&a=send&b=1" method="post" name="" id="">

 <table width="50%" border="0" align="center" cellpadding="4" cellspacing="0">



<tr>

     <td width="22%">To</td>

     <td width="78%"><input name="to_user" type="text" id="to" value="$user"></td>

   </tr>

<tr>

  <td>From</td>

  <td> $username </td>

</tr>

   <tr>

     <td>Message</td>

     <td>

<textarea name="message" id="message" rows="5" cols="50">&nbsp;</textarea></td>

   </tr>

   <tr>

     <td>Private</td>

     <td>

<input type="checkbox" name="private" $value></td>

   </tr>

   <tr>

     <td>&nbsp;</td>

<input name="from" type="hidden" id="from" value="$username">

     <td><input type="submit" name="Submit" value="Submit"></td>

   </tr>

 </table>

</form>



HTML;

?>




SECOND. Include the following at the top of the content. This will produce a notice at the top which should stay for one minute before dissapearing again.

CODE


<?

include 'db.php';

///connect to database - file content is shown near the bottom



include 'formtemplates.php';

///include the send form as shown above.



/////these variables are explained at the bottom :)

$page = $_GET['page'];

$a = $_GET['a'];

$b = $_GET['b'];

$user = $_GET['user'];



if (isset($_SESSION['username'])) {

/*-------------------------------------------------------------------------------------*/

print "<i>";



///you will need to adjust these to reflect your log on script - mine uses sessions with these variables



$last_login = $_SESSION['last_login'];

$username = $_SESSION['username'];

$firstname = $_SESSION['first_name'];

$userid = $_SESSION['userid'];



///retrieve the latest known time the user logged in

$last_login_ = mysql_query("SELECT last_login,im_update FROM users WHERE userid=$userid LIMIT 1") or die("MySQL Error: " . mysql_error());

while($last = mysql_fetch_array($last_login_)) {

$last_login = $last['last_login'];

$im_update = $last['im_update'];

}



/////if ($im_update == 0) {

/* to save complexity ive removed this bit - which links to the user table to allow users to decide if they wish to be updated*/



//get all messages for the user where the message date is after the last login time

$sql_messagenew = mysql_query("SELECT * FROM message WHERE to_user='$username' AND date >'$last_login' ORDER BY id desc");

$new_row = mysql_num_rows($sql_messagenew);



//if there is more than 0 new records then display them - how you wish, the following way is one possibility



if ($new_row !== 0) {

print "$firstname You have ($new_row) new Instant messages:";





print "<table width="90%" border="1" align="center" cellpadding="4" cellspacing="0">";

print " <tr> ";

print "      <td width="15%">To</td>";

print "      <td width="15%">From</td>";

print "      <td width="50%">Message</td>";

print "      <td width="10%">Date</td>";

print "      <td width="10%">Type</td>";

print "    </tr>  ";



/// display each row that matches the query

while($row=mysql_fetch_array($sql_messagenew)) {

print '<tr><td valign="top"><a href="?page=users&a='.$row['to_user'].' ">'.$row['to_user'].'</a></td><td valign="top"><a href="?page=users&a='.$row['from'].' ">'.$row['from'].'</a></td><td valign="top">'.$row['message'].'</td><td valign="top">'.$row['date'].'</td><td valign="top">'.$row['type'].'</td></tr>  ';

}

/*---*/

print "</table>";

////end table///



print "<br /><br />";

} else {

//print "$firstname You Have (0) New Instant Messages.";

//print "<br /><br />";

}

//get the current date

     $date=time();

$date = $date+18000;

//adjust to gmt



$sql = mysql_query("UPDATE users SET last_login=FROM_UNIXTIME($date) WHERE userid='$userid'");

//update the last log in time



//} this is the close tag for choosing to revieve the update



print "</i>     n";



/*----------------------------------------------------------------------------*/

}





?>








THIRD. The following is the script to send IM's and to view them to be placed in the body of the page. To access this you will need to go to file.php?page=message where 'file.php' can be a *.php file with any name.


CODE


<?

if ($page == message) {

/*----------------------------------Message---------------------------------*/

Print "Instant Message System<br />";

Print "<a href=?page=users>- Member List</a><br />";

/*when page = users my site lists the active users. This is not explained in this tutorial - but can be done fairly quickly */



if ($a == send) {

///the section that allows messages to be sent...

if ($b == 1) {

///insert data to database



     $date=time();

$date = $date+18000;

///set the time

$date = $date + 60

///set a minute delay to leave the IM's showing on the screen after page refreshes



$to_user = $_POST['to_user'];

$from = $_POST['from'];

$message = $_POST['message'];

$private = $_POST['private'];

$type = "IM";



///set the var's



/* if private - my script doubles as a comment system,

where it is not private i can link it to news posts etc

e.g. send comments to news_1 and retrieve them when to_user isnt in the user table*/



if(!isset($private)) {

$private = 0;

} else {

$private = 1;

}



//some data validation

if (empty($to_user) || empty ($from) || empty($message) || ($message == " ") || empty($date)) {



$message = 'You Need To Complete All Required Fields';

  } else {

//everything ok, strip slashes, link links and submit to db

$message = stripslashes($message);



$message = eregi_replace(

   "(http|https|ftp)://([[:alnum:]/n+-=%&:_.~?]+[#[:alnum:]+]*)",

   "<a href="1://2" target="_blank">1://2</a>",

   $message);



     mysql_query("INSERT INTO `message` ( `id` , `to_user` , `from` , `message` , `date` , `private` , `type` ) VALUES('','{$to_user}','{$from}','{$message}',FROM_UNIXTIME($date),'{$private}','{$type}')");



 $message = "<br />Successfully Posted Message";



}



}

print $message;

print "<br /><br />";

$change = read;

print "<a href="?page=$page&a=$change">$change Message</a><br> n";

print "<br>    n";

print $send_message;



} else {

///section = read...

$a = read;

print "<br/>";

$change = send;

print "<a href="?page=$page&a=$change">$change Message</a><br> n";

print "<br>    n";

/*-------*/



///display them...



print "<table width="90%" border="1" align="center" cellpadding="4" cellspacing="0">";

print " <tr> ";

print "      <td width="15%">To</td>";

print "      <td width="15%">From</td>";

print "      <td width="50%">Message</td>";

print "      <td width="10%">Date</td>";

print "      <td width="10%">Type</td>";

print "    </tr>  ";





$user = $_GET['user'];



///if not to a user, display all the public messages

if (empty($user)) {

///////////

/*---*/

$message_query = mysql_query("SELECT * FROM message WHERE private='0' order by id desc");

$row_num_ = mysql_num_rows($message_query);



while($row=mysql_fetch_array($message_query)) {



print '<tr><td valign="top"><a href="?page=users&a='.$row['to_user'].' ">'.$row['to_user'].'</a></td><td valign="top"><a href="?page=users&a='.$row['from'].' ">'.$row['from'].'</a></td><td valign="top">'.$row['message'].'</td><td valign="top">'.$row['date'].'</td><td valign="top">'.$row['type'].'</td></tr>  ';



}

/*---*/

} else {

///the user isnt empty - is it to a website user, or to a news post?



/*----------------------------*/

$username = $_SESSION['username'];

if ($user !== $username) {



///if the user has admin settings allow him to view the private messages of other users

if($_SESSION['user_level'] > 2){

/*---*/

////////////////*------0--------*/////////

$row_num = $row_num_0;

$message_query_0 = mysql_query("SELECT * FROM message WHERE to_user='$user' ORDER BY id desc LIMIT 10");

$row_num_0 = mysql_num_rows($message_query_0);



while($row=mysql_fetch_array($message_query_0)) {



print '<tr><td valign="top"><a href="?page=users&a='.$row['to_user'].' ">'.$row['to_user'].'</a></td><td valign="top"><a href="?page=users&a='.$row['from'].' ">'.$row['from'].'</a></td><td valign="top">'.$row['message'].'</td><td valign="top">'.$row['date'].'</td><td valign="top">'.$row['type'].'</td></tr>  ';



}

/*---*/

} else {

/*--user doesnt have admin settings - only able to view public messages to other users-*/

////////////////*------1--------*/////////

$row_num = $row_num_1;



$message_query_1 = mysql_query("SELECT * FROM message WHERE private='0' AND to_user='$user' ORDER BY id desc LIMIT 10");

$row_num_1 = mysql_num_rows($message_query_1);



while($row=mysql_fetch_array($message_query_1)) {

print '<tr><td valign="top"><a href="?page=users&a='.$row['to_user'].' ">'.$row['to_user'].'</a></td><td valign="top"><a href="?page=users&a='.$row['from'].' ">'.$row['from'].'</a></td><td valign="top">'.$row['message'].'</td><td valign="top">'.$row['date'].'</td><td valign="top">'.$row['type'].'</td></tr>  ';



}

/*---*/

}

} else {

///user is the same as the one for which messages are requested - so show all their private messages

/*---*/

////////////////*------2--------*/////////

$row_num = $row_num_2;



$message_query_2 = mysql_query("SELECT * FROM message WHERE to_user='$user' ORDER BY id desc LIMIT 10");

$row_num_2 = mysql_num_rows($message_query_2);



while($row=mysql_fetch_array($message_query_2)) {



print '<tr><td valign="top"><a href="?page=users&a='.$row['to_user'].' ">'.$row['to_user'].'</a></td><td valign="top"><a href="?page=users&a='.$row['from'].' ">'.$row['from'].'</a></td><td valign="top">'.$row['message'].'</td><td valign="top">'.$row['date'].'</td><td valign="top">'.$row['type'].'</td></tr>  ';



}

/*---*/

}

/*----------------------------*/

///////

}

print "</table>";

////end table///

/*-------*/

}

///if a variable is for all... then show all ones available

$c = $_GET['c'];

if($c == all) {



print "<table width="90%" border="1" align="center" cellpadding="4" cellspacing="0">";

print " <tr> ";

print "      <td width="15%">To</td>";

print "      <td width="15%">From</td>";

print "      <td width="50%">Message</td>";

print "      <td width="10%">Date</td>";

print "      <td width="10%">Type</td>";

print "    </tr>  ";



///if admin show all messages, if not exclude - ive taken out pagination as there is another tut, and i cba :)

if($_SESSION['user_level'] > 2){

/*-----------------------------------------------------------------------------------------------------------------------*/

////////////////*------3--------*/////////

$row_num = $row_num_3;



$message_query_3 = mysql_query("SELECT * FROM message ORDER BY id desc");

$row_num_3 = mysql_num_rows($message_query_3);



while($row=mysql_fetch_array($message_query_3)) {



print '<tr><td valign="top"><a href="?page=users&a='.$row['to_user'].' ">'.$row['to_user'].'</a></td><td valign="top"><a href="?page=users&a='.$row['from'].' ">'.$row['from'].'</a></td><td valign="top">'.$row['message'].'</td><td valign="top">'.$row['date'].'</td><td valign="top">'.$row['type'].'</td></tr>  ';

}

/*-----------------------------------------------------------------------------------------------------------------------*/

} else {

 echo "Your userlevel does not authorise you to view this page";

}

/*-----------------------------------------------------------------------------------------------------------------------*/

print "</table>";

////end table///



}



/*----------------------------------End Message------------------------------*/

}

?>




The MYSQL tables i have used here are 'users' and 'message'

Message is shown below
CODE


CREATE TABLE `message` (

 `id` int(11) NOT NULL auto_increment,

 `to_user` varchar(30) NOT NULL default '',

 `from` varchar(30) NOT NULL default 'Guest',

 `message` text NOT NULL,

 `date` datetime NOT NULL default '0000-00-00 00:00:00',

 `private` enum('0','1') default '0',

 `type` varchar(10) default 'IM',

 PRIMARY KEY  (`id`)

) TYPE=MyISAM AUTO_INCREMENT=33;



Users is shown below
CODE


CREATE TABLE `users` (

 `userid` int(25) NOT NULL auto_increment,

 `first_name` varchar(25) NOT NULL default '',

 `last_name` varchar(25) NOT NULL default '',

 `email_address` varchar(35) NOT NULL default '',

 `mailing_list` enum('1','2') NOT NULL default '1',

 `age` smallint(6) default NULL,

 `location` text,

 `username` varchar(25) NOT NULL default '',

 `PASSWORD` varchar(255) NOT NULL default '',

 `info` text NOT NULL,

 `user_level` enum('0','1','2','3') NOT NULL default '1',

 `signup_date` datetime NOT NULL default '0000-00-00 00:00:00',

 `last_login` datetime NOT NULL default '0000-00-00 00:00:00',

 `activated` enum('0','1') NOT NULL default '0',

 `im_update` enum('0','1') default '0',

 PRIMARY KEY  (`userid`),

 KEY `PASSWORD` (`PASSWORD`),

 KEY `email_address` (`email_address`),

 KEY `activated` (`activated`),

 KEY `mailing_list` (`mailing_list`)

) TYPE=MyISAM COMMENT='Membership Information' AUTO_INCREMENT=33;



db.php is the file used to connect the the mysql database. If this is not working you may recieve a series of errors. You will need to create a file, insert the following php code, and save it as db.php.

The content is shown below:
CODE


<?

//set database connection variables

$hostname='localhost';

$uname='';

$password='';

$database='';



//establish database connection

$connect = mysql_connect($hostname,$uname,$password);



//display error if connection fails

if ($connect==FALSE) {



  print 'Unable to connect to database: '.mysql_error();



} else {



//select database

mysql_select_db($database);

}

?>



Information for link creation / running the script.
----------------------------------------------------------------------------
In php you can append data to urls e.g. file.php?a=1
you can then parse this to a php variable.

this script uses the following examples:

when the loaded page = ?page=message
it shows all the public messages.

when it = ?page=message&a=send&user=user1
it shows the send form with user1 in the to field

?page=message&a=read&user=user1
shows messages to user1.
If the same user user is logged in it shows all messages, if not it shows public messages.

If an admin requests it ($_SESSION['user_level'] over 2) it shows all messages.

when the form is sent it goes to ?page=message&a=sent&b=1
to insert the data to the database.
----------------------------------------------------------------------------

I admit that when i made it it was for personal use and not as a tutorial. I hope that ive given enough details, if not let me know and i will try and reslove it, or inform me of any changes you make so i can update this.

enjoy smile.gif - once you have it working can you post a reply at the bottom so i know, if your the first person to do so

 

 

 


Reply

deheleri
Do you have an example anywhere? Because this looks really cool.

Reply

Meeko
I agree. I demo would be much appreciated.

Reply

welbis
i dont - only on my website, but cos im still developing that i havnt got many users on there. You're welcome to register if you like - you should get a welcome IM that will show you what its like.

When ive got the site running ill email everyone who has registered to say - so If you dont want me to email you once ive got the site working then stick 'test' or 'dont email or 'delete me'' in the user info section of the log in form so i can delete you when its all up and running.

www.jesus-freaks.co.uk

Also, cos the way it displays is quite easily customised with a little html knowledge a demo wont really help (i think there are 3 sections that need changing - i was going to make it a template to include but couldnt be bothered - so your welcome to adjust it) - im planning to change the way mine displays after a while anyway - though this suffices. I figured if by some freak chance it became a popular system then if everyone was using my layout id look like a copy lol smile.gif

Basically at the moment it just loooks like this in a bordered table with a bit of spacing..:


to from message date type
user1 user2 hello 22:00 11/10/04 user
user1 admin hi 23:32 11/10/04 admin


^but i might change mine to be more like:

You have recieved (2) new IM's:

from admin (admin)
message: blah
blah blah
date: ....

from user 1 (User)
message: blah
blah blah
date: ....

 

 

 


Reply

netdroid9
How about a time as well biggrin.gif

Reply

welbis
that records the time in the same field as the date column and prints it all together

You can split it with one line of php commands if you want

Reply

WhiteBlaze
Now thats a amazing script when ever I get my site up and running I'll have to give it a try! Thanks allot for sharring! smile.gif

Reply

y04chs067
Yep,i agree!Can you let us downloadthe script onceyou have finished?

Reply

welbis
the IM stuff here is finished... and cos it works within your own site i cant make a copy for it unless i give you my whole cms system - which isnt finished

Reply

brad
Thats sweet man...

Reply

Latest Entries

welbis
Yeah it works a bit like PMs, but when you get a new one it prints a little box at the top of the screen above the content for 2 minutes after its sent.

If you want a demo, then go to my site, register, and send yourself a PM.

If you dont want me to send you an email when i've finished my site then put 'delete me' in the info field when you sign up.

Reply



Got an Opinion! Express your Views! (no registration):-
Add your Reply/ Opinion/ Views/ Comments/ Suggestion/ Questions/ Queries etc.
Posts with decent grammar & English will be accepted and please refrain from profanities.
For asking a Question, We recommend you to sign-up (for free) so that you can track the topic easily.

Nature of your Post*: Opinion/ Reply/ Comments
Question/Query
Feedback to us.
       
Name   Email
Title/Question*

(Maximum characters: 10,000)
You have characters left.

Pages: 1, 2
Similar Topics

Keywords : message v0 updated

  1. Should Religion Be Updated? - debate modern religion today (poll) (47)
    Religion is outdated, it hasn;t developed as society did. women can't be priests in nearly every
    christian religion and definitely cannot be a part of the higher church echelon. confoms sexuality,
    marrige. On all of these topics the church and christianity seems to be out of date with normal
    world opinions. in my view the chuirch needs a haulover. One thing is strange thought... numbers
    of members of protestant churches have been on the increase in the states and more young people are
    getting married! ca it be that society has become so fragmented that people c...
  2. Useless Topics. Message To Trap17 Admins. - (6)
  3. Coco Pops - and it's secret message (3)
    I was eating coco pops while chatting to some mates and we started discussing the Coco pops story. I
    don't know if it's the same in other countries but here in the UK the story on the back of
    the packet, and on the TV adverts, usually involve Coco and his gang trying to stop Croc and his
    gorilla henchmen from getting any coco pops. Well we (friends and me) got to thinking that this is
    sending a bad message out to kids. It's teaching them not to share. I mean Coco seems to have
    an unlimited supply of coco pops but he never gives any to Croc. I'm sure if ...
  4. Error Message - (6)
    I'm getting this error message when using 'Gallery' and PHP Nuke. If you know how to fix it,
    please let me know. I will give you 300FNH$! Error Message as follows:--- Warning:
    opendir(http://www.unis.freenukehosting.com/modules/gallery/watermark): failed to open dir: not
    implemented in /home/unisfre/public_html/modules/gallery/layout/watermarkform.inc on line 58 Could
    not open directory http://www.unis.freenukehosting.com/module...watermarkError: 86...
  5. Forums Rules & Important Information ~ Updated 12/03/05 - (0)
    Welcome To Free Nuke Hosting Index 1. Forum Rules 2. Terms of Service 3. Music Rules
    4. FAQs 5. Trading Market
    ******************************************************************** Please read carefully so that
    you do not get in trouble with the site staff.
    ********************************************************************* 1. Forum Rules
    You are not allowed to Post: Links To: Child Pornography Adult Content Torrents files
    Warez (P2P) Illegal Content Posts Should Not Include: Spam Cracks Or Ser...
  6. How To Request Free Hosting-*Must Read *(Updated by Naz+Haz) - (1)
    FREE HOSTING IS BACK! Please read carefully so that your application will not be rejected!
    ----------------------------------------------------- Hello, freenukehosting.com offers 800 Mb
    space and 10 Gb bandwidth. Here is how you can request hosting. You must have 5 posts before
    requesting . Post a new topic by clicking on the new topic button located on every page. Please
    use this template as it allows the account creators to process accounts quicker.
    ######Template###### Subject Of The Topic: Request Free Hosting Message Body: *Domain
    Nam...
  7. Error message - (2)
    Please, I am trying to upload a jpg avatar and receive this message each time : Warning:
    copy(./images/avatars/15125530994219c468cd169.jpg): failed to open stream: Permission denied in
    /home/freenuke/public_html/forums/includes/usercp_avatar.php on line 227 Warning: Cannot modify
    header information - headers already sent by (output started at
    /home/freenuke/public_html/forums/includes/usercp_avatar.php:227) in
    /home/freenuke/public_html/forums/includes/page_header.php on line 477 Warning: Cannot modify
    header information - headers already sent by (output started...
  8. My Sites Updated PHP-Nuke/PHP-Nuke Platinum/Zentri Portal - (4)
    hello everyone ive got the sites back up all but zentri right now you can see them here :arrow:
    www.nuke-resources.info :arrow: www.nuke-resources.info/nuke/index.php working on this one right
    now :arrow: www.nuke-resources.info/zentri ...
  9. phpmyadmin error message - (1)
    it says below message. it works fine though. Notice: Undefined variable: hash in
    /usr/local/cpanel/base/3rdparty/phpMyAdmin/queryframe.php on line 180 Notice: Undefined variable:
    hash in /usr/local/cpanel/base/3rdparty/phpMyAdmin/queryframe.php on line 292...
  10. Website Updated Added A Poll - (9)
    hi everyone ive added a poll to this topic now 8)...
  11. Website Has Been Updated - (11)
    ive added tons of stuff to my nuke site please give me some feedback on this maybe evensome votes on
    it if you would like to have your site added to top sites goto my website and your site ive added a
    module into the site so go add your site and get some popularity /biggrin.gif' border='0'
    style='vertical-align:middle' alt='biggrin.gif' /> its called ...
  12. Updated My Website - (30)
    Take A Look Hope You Like It Allthough Im Not Finished With It Yet Lets Here Some Votes On It On The
    Opening Page The Spot Where It Says DFLW-DFTFD Is A Little Poor But Its The Process Of Being Fixed
    http://www.dflw-tfd.freenukehosting.com/ And Please Feel Free To Register On The Site Much TYs...
  13. My Site...Well message board - (9)
    Come have a look at my message board we have not set up a website yest but we are planning to at the
    moment we are just putting ideas into it and hopefully iy will look like a pro site well here is the
    forum http://www.gaming.freenukehosting.com/ Please tell me what you think of it...
  14. errors showing when sig/avie updated - (0)
    Just to let you know, when I updated my sig etc, there was some errors... QUOTE Warning:
    copy(./images/avatars/238094973419d497283d6e.jpg): failed to open stream: Permission denied in
    /home/cops/public_html/forums/includes/usercp_avatar.php on line 227 Warning: Cannot modify
    header information - headers already sent by (output started at
    /home/cops/public_html/forums/includes/usercp_avatar.php:227) in
    /home/cops/public_html/forums/includes/page_header.php on line 475 Warning: Cannot modify header
    information - headers already sent by (output started at /home...



Looking for instant, message, system, v0, 9, updated, work

*RANDOM STUFF*





*SIMILAR VIDEOS*
Searching Video's for instant, message, system, v0, 9, updated, work

*MORE FROM TRAP17.COM*
advertisement



Thorough instant message system V0.9 [UPDATED to work]



 

 

 

 

ADD REPLY / Got an Opinion! a humble request :-) RAPID SEARCH! Free Hosting [X]
Express your Opinions, Thoughts or Contribute your information that might help someone here.
Ask your Doubts & Queries to get answers.. "Together, We enlight each other!"
Register FREE for AD-FREE forum, Create your own topics, Ask Questions, track topics, setup subscriptions & notifications and Get a Free Website w/ Email and FTP.
500MB Space *No Ads*, CPanel, FTP, PHP, MySQL, EMails - 100% FREE