April 3, 2019

Universal Forum Version 6


Hard to believe I've been working on this little project for six years. Anyhow, I've made quite a few changes since the last version. The PHP Source Code will be pasted below. In all the previous posts I've deleted the change log before I posted the source, so here it is in its entirety:

2019-03-20 v6.0 (still)
Commented all my code.

2019-03-13 v6.0
Added email thing.

2019-03-13 v5.9
Implemented super-kickass post bubble and message color definer to make it obvious who is who.

2019-01-20 v5.8 (still)
Refined spam measures further, notably added specific SVG icon to denote spammers.

2019-01-01 v5.8
Added spam counter-measures.

2018-07-28 v5.7 (still)
Removed a bunch of fancy bullshit. Added speech bubble unicode.

2018-01-13,27 v5.7
Changed color scheme to match site index. Removed dynamic scale to simplify compatibility. Fixed eye icon SVG to be scale consistent, also improved aesthetic. Removed autofocus attribute because it was really annoying!

2017-03-22 v5.6
Added custom IP code & SVG to show who the admin is.

2017-03-21 v5.5
Integrated changelog directly into source.
Removed custom font settings and replaced with generic web defaults to make even more universal.
Added favicon inline as base64 encode.

2016-01-03 v5.4
Due to unicode inconsistency, tombstone is replaced with dynamic inline SVG 'eye' glyph with RBGA IP iris.
This change log is now linked from the php source code of the forum.

2016-01-02 v5.3
New IP & timestamp system is overhauled and streamlined to display only as a tooltip embedded in avatar.
Avatar is changed from inverse smiley face to more neutral 'tombstone'.

2015-12-21 v5.2
Added major innovation: IP address is now converted to RGBA & applied to unicode avatar for each post.
Form placeholder now notifies posters that their IP will be publicly displayed.

2015-09-01 v5.1
Implemented IP address inclusion in post purely as an anti-spam measure.
Blocked two Chinese domains which were spamming thousands of comments per hour.

2015-08-12 v5.0
Major innovation: css transform operator added to introduce correct reverse-chronological ordering of comments.
General visual styling is significantly gussied up.

2015-06-21 v4.1
Major innovation: css calc operators added to introduce dynamic scaling of all elements.

2014-02-20 v4.0
Font links changed from opentype to woff.
Removed 'Name' Input Field since it was inherently pointless.

2014-02-20 v3.1
Forum closed due to spam.
No major changes.

2013-03-05 v3.0
Version added to page title.
Major innovation: closed loop meta refresh is incorporated to automate feedback.
Minor cosmetic changes to css.

2012-09-12 v2.3
Universal Forum leaves Beta, basic functionality and features are enabled.
Added default timezone & error reporting to maximize php sever compatibility.

===============================================================

<?php
date_default_timezone_set('America/Los_Angeles');
error_reporting (E_ALL ^ E_NOTICE);
echo "<!doctype html><html><head><meta charset='UTF-8'>

<title>Universal Forum v6.0</title>

<link href='data:image/svg+xml;base64,AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAD/AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMwAAADMzMzMAERERADMzMBERERERAzMBEQAAABEQMBEAIiIiABEAACIiIiIiAAARACIiIgARAwERAAAAERAzMBERERERAzMzAREAERAzMzMwADMAAzMzMzMzMzMzMzMzMzMzMzMzP//wAA//8AAP//AAD4HwAA4AcAAMADAACAAQAAAAAAAAAAAAAAAAAAgAEAAMADAADgBwAA8Y8AAP//AAD//wAA' rel='icon' type='image/svg+xml'/>

<style>

body
{
margin: 0%;
padding: 0%;
background-color: #161616;
color: white;
}

.flip
{
transform: scaleY(-1);
margin: 0%;
padding: 0%;
}

.form
{
margin: 1%;
font-family: sans-serif, monospace;
font-size: 24px;
}

#textarea
{
font-family: sans-serif, monospace;
font-size: 24px;
background-color: black;
color: white;
}

#button
{
padding: 10px;
vertical-align: top;
font-family: sans-serif, monospace;
font-size: 24px;
}

.bubble
{
background-color: #000000;
transform: scaleY(-1);
margin: 1%;
padding: 1%;
border-radius: 6px;
font-family: sans-serif, monospace;
font-size: 24px;
font-weight: bold;
}

</style>
</head>
<body>

<div class='form'>
<form action='index.php' method='post'>
<textarea  name='comment' placeholder='comment' id='textarea'></textarea>
<input type='submit' value='POST' id='button'>
</form>
</div>
<div class='flip'>
";
$ip = $_SERVER['REMOTE_ADDR']; //get the ip address of the comment poster
$file = "index.php";
$name = fopen($file, 'a') or die("fail"); //open this document to begin appending comments
if ($_POST["comment"]=="")
echo "";
else
{
echo "";

list($r, $g, $b, $a) = explode('.', $ip); //parse the ip address and asign each section to RGBA values, also their inverse
$x = 255-$r;
$y = 255-$g;
$z = 255-$b;

fwrite($name, $string); //set the comment bubble color and text according to the ip RGBA values above
$string = "<div style='background-color: rgba($r,$g,$b,$a); color: rgba($x,$y,$z,1); -webkit-text-stroke: 1px black;' class='bubble'>";

fwrite($name, $string);
$string = strip_tags($_POST["comment"]); //post the visitors comment to the page

$message = $_POST["comment"];

ini_set('SMTP','localhost');
ini_set('smtp_port','25');
ini_set('sendmail_from','x@y.com'); //tell the mail fuction how to do its job

mail('x@y.com','Universal Forum Comment',$message,"From: $ip"); //email the comment to the specified address

$string = preg_replace('/(http|www|url)/', "<span style='color:lightpink;'>SPAM</span>", $string); //filter out spam keywords like TLD etc.

$string = preg_replace('/\\b\\.com\\b/', "<span style='color:lightpink;'>.spam</span>", $string);
$string = preg_replace('/\\b\\.net\\b/', "<span style='color:lightpink;'>.spam</span>", $string);
$string = preg_replace('/\\b\\.org\\b/', "<span style='color:lightpink;'>.spam</span>", $string);
$string = preg_replace('/\\b\\.info\\b/', "<span style='color:lightpink;'>.spam</span>", $string);
$string = preg_replace('/\\b\\.ml\\b/', "<span style='color:lightpink;'>.spam</span>", $string);
$string = preg_replace('/\\b\\.ru\\b/', "<span style='color:lightpink;'>.spam</span>", $string);
$string = preg_replace('/\\b\\.pro\\b/', "<span style='color:lightpink;'>.spam</span>", $string);
$string = preg_replace('/\\b\\.ly\\b/', "<span style='color:lightpink;'>.spam</span>", $string);
$string = preg_replace('/\\b\\.online\\b/', "<span style='color:lightpink;'>.spam</span>", $string); //TLD filter added 2019-03-21

if (preg_match('/(SPAM)/', $string)):

fwrite($name, $string);
$string = " <span style='color:red;'><b>(THIS POST IS SPAM)</b></span>"; //flag spam as spam

else:

endif;

if ($ip == '0.0.0.0'): //assign icon to the admin (your IP address goes here)
fwrite($name, $string);
$string = " <svg width='16px' height='16px' viewBox='0 0 100 100'><path fill='darkgoldenrod' d='M50,0a50,50,0,0,0,0,100z'/><path fill='goldenrod' d='M50,0a50,50,0,0,1,0,100z'/><path fill='goldenrod' d='M50,25a25,25,0,0,0,0,50z'/><path fill='darkgoldenrod' d='M50,25a25,25,0,0,1,0,50z'/><title>";

elseif (preg_match('/(SPAM)/', $string)): //assign icon to spammers
fwrite($name, $string);
$string = " <svg width='16px' height='16px' viewBox='0 0 100 100'><path d='m88 68v-43.999s-20-20.001-28-20.001-52 12-52 24 0 32 0 44 20 20 28 20 52-12 52-24z' fill='#E2BEA3'/><g stroke-linejoin='round' stroke='#CEB3A1' stroke-linecap='round' stroke-width='2' fill='none'><line x1='16.001' y2='80' x2='16' y1='44'/><line x1='76' y2='76' x2='76' y1='40'/><line x1='64' y2='80' x2='64' y1='44'/><line x1='52' y2='84' x2='52' y1='48'/><line x1='40' y2='88' x2='40' y1='52'/></g><path d='m88 24c0-12-20-20-28-20s-52 12-52 24 20 20 28 20 52-12 52-24z' fill='#EDC6B7'/><title>";

else:
fwrite($name, $string); //asign icon to random visitors
$string = " <svg width='16px' height='16px' viewBox='0 0 100 100'><path d='m1 50s21-28 49-28 49 28 49 28-21 28-49 28-49-28-49-28z' fill='white'/><path d='m78 50c0 15.463-12.53 28-28 28-15.463 0-28-12.537-28-28s12.537-28 28-28c15.47 0 28 12.537 28 28z' fill='rgba($r,$g,$b,$a)'/><path d='m64 50c0 7.7383-6.2686 14-14 14s-14-6.2617-14-14c0-7.7314 6.2686-14 14-14s14 6.269 14 14z'/><title>";

endif;

fwrite($name, $string);
$string = date("Y-m-d", time()); //create icon and asign it a tooltip including timestamp and ip address

fwrite($name, $string);
$string = "&nbsp;&#149;&nbsp;";

fwrite($name, $string);
$string = date("H:i:s", time());

fwrite($name, $string);
$string = "&nbsp;&#149;&nbsp;";

fwrite($name, $string);
$string = "$ip";

fwrite($name, $string);
$string = "</title></g></svg> ";

fwrite($name, $string);
$string = "</div>";

fwrite($name, $string);
$string = "

";

fwrite($name, $string);
fclose($name);

if ($_POST["comment"]=="")
echo "";

else
{
echo('<meta http-equiv="refresh" content="1">'); //wait one second then reload the page to display the most recent comments
}
}
?>

June 25, 2015

Universal Forum Version 5

The last update I made to my Universal Forum Script was on March 5, 2013. This updated version 5 is greatly improved, albeit more advanced and hence less 'universal'. My script is unique in that it solves three fundamental problems in atypical ways:

1. Entire forum is contained in a single PHP file, including all the code that makes it work.
This is done using fwrite to append form data to the end of the source file.

2. The forum automatically refreshes the page after each comment is made.
If else rules are exploited to execute a non-recursive meta refresh.

3. Posts are displayed in reverse-chronological order!
Recursive CSS transform flipping makes the impossible possible.


These are mainly very typical forum attributes, the thing that makes them unique is that they are all accomplished using extremely light-weight and elegant functions. The entire script is only 2428 characters. Those are the main new improvements, above and beyond that the styles have been adjusted to improve legibility and scale every element dynamically to fit any viewport.

Please play with the source code to explore all its features:



<?php
date_default_timezone_set('America/Los_Angeles');
error_reporting (E_ALL ^ E_NOTICE);
echo "<!doctype html><html><head>
<meta http-equiv='content-type' content='text/html; charset=UTF-8'><title>Universal Forum v5</title>
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
<style>

body
{
background-color: whitesmoke;
margin: 0%;
padding: 0%;
}

.flip
{
transform: scaleY(-1);
margin: 0%;
padding: 0%;
}

.form
{
margin: 1%;
font-family: 'Source Sans Pro';
font-size: calc(100vw / 50);
}

#textarea
{
font-family: 'Source Sans Pro';
font-size: calc(100vw / 50);
}

#button
{
height: calc(100vw / 12);
width: calc(100vw / 12);
padding: 1%;
vertical-align: top;
text-shadow: 1px 1px white;
font-family: 'Source Sans Pro';
font-size: calc(100vw / 50);
}

.bubble
{
background-color: white;
transform: scaleY(-1);
margin: 1%;
padding: 1%;
border-radius: 6px;
box-shadow: 1px 1px 3px lightgray;
font-family: 'Source Sans Pro';
font-size: calc(100vw / 50);
}

.timestamp
{
margin-left: 40%;
margin-right: 40%;
background: radial-gradient(circle, rgba(245,245,245,1) 0%, rgba(245,245,245,1) 50%, rgba(0,0,0,0) 100%);
margin-top: -2%;
color: red;
font-family: 'Source Sans Pro';
font-size: calc(100vw / 75);
}

</style>
</head>
<body>
<div class='form'>
<form action='index.php' method='post'>
<textarea autofocus rows='3' cols='50' wrap='virtual' name='comment' placeholder='comment' id='textarea'></textarea>
<input type='submit' value='POST' id='button'>
</form>
</div>
<div class='flip'>
";
$file = "index.php";
$name = fopen($file, 'a') or die("fail");
if ($_POST["comment"]=="")
echo "";
else
{
echo "";

fwrite($name, $string);
$string = "<div class='bubble'>";

fwrite($name, $string);
$string = "<div class='timestamp'><center>";

fwrite($name, $string);
$string = date("y.m.d", time());

fwrite($name, $string);
$string = " · ";

fwrite($name, $string);
$string = date("H:i:s", time());

fwrite($name, $string);
$string = "</center></div>";

fwrite($name, $string);
$string = strip_tags($_POST["comment"]);

fwrite($name, $string);
$string = "</div>";

fwrite($name, $string);
$string = "

";

fwrite($name, $string);
fclose($name);

if ($_POST["comment"]=="")
echo "";

else
{
echo('<meta http-equiv="refresh" content="1">');
}
}
?>

March 5, 2013

Universal Forum Version 3


Version 3 of a php microforum that I wrote, consisting of a single self-referencing script. With just the click of a button the script appends name and comment field data to itself, then refreshes a second later. There are lots of other subtle features, but instead of blathering on about them here I'll let you examine them directly in the complete source code:


<?php
date_default_timezone_set('America/Los_Angeles');
error_reporting (E_ALL ^ E_NOTICE);
echo "<!doctype html><html><head>
<meta http-equiv='content-type' content='text/html; charset=UTF-8'><title>Universal Forum v3</title>
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
<style>
body{margin:0%;padding:0%;background-color:white;font-family: 'Source Sans Pro', sans-serif;font-size:20px;}
.form{margin:2%;}
#textarea{font-family: 'Source Sans Pro', sans-serif;font-size:20px;}
#button{
padding-left:1%;padding-right:1%;padding-top:3%;padding-bottom:3%;vertical-align:top;font-family: 'Source Sans Pro', sans-serif;font-size:40px;}
.bar{padding:1%;background-color:black;text-align:center;font-weight:bold;}
.bubble{margin:1%;padding:1%;border:1px solid whitesmoke;border-radius:3px;background-color:ghostwhite;}
</style>
</head><body>
<div class='form'><form action='index.php' method='post'><input type='text' name='x' placeholder='name' id='textarea';'><br><textarea rows='6' cols='30' wrap='virtual' name='y' placeholder='comment' id='textarea';'></textarea><input type='submit' value='✎post' id='button'></form></div>";
$file = "index.php";
$name = fopen($file, 'a') or die("fail");
if ($_POST["y"]=="")
echo "<div class='bar'><font color='yellow'>you must enter something to post</font></div>";
else
{
echo "<div class='bar'><font color='lime'>comment posted!</font></div>";
fwrite($name, $string);
$string = "<div class='bubble'><font color='blue'><b>";
fwrite($name, $string);
$string = strip_tags($_POST["x"]);
fwrite($name, $string);
$string = "</b></font> ";
fwrite($name, $string);
$string = "<font color='silver'>(";
fwrite($name, $string);
$string = date("y.m.d H:i:s", time());
fwrite($name, $string);
$string = ")</font><br>❝";
fwrite($name, $string);
$string = strip_tags($_POST["y"]);
fwrite($name, $string);
$string = "❞</div>";
fwrite($name, $string);
fclose($name);
if ($_POST["y"]=="")
echo "";
else
{
echo('<meta http-equiv="refresh" content="1">');
}
}
?>

August 27, 2011

Second Life Mesh IP Tutorial Answers


Part of the new policy with mesh rollout comes in the form of this ridiculous and patronizing "Intellectual Property" tutorial. Since I was already participating in the mesh beta I was actually forced to take this asinine "tutorial" twice. Unforgivable. And fuck everything about this. Following are the correct answers to all the questions, just select the corresponding radio buttons and you're golden.

Second Life Mesh IP Tutorial

Daniel is a very talented artist. He is also a huge movie fan. Daniel made a 3D model that looks just like a character from his favorite movie and wants to use it as an avatar in Second Life. Can Daniel upload his 3D model as a mesh and use it for his Second Life avatar?

01. NO

Maria has created an avatar that closely resembles her favorite movie star. The avatar is composed of several highly detailed meshes and textures that Maria made by using 3D modeling software and other graphic tools. When is it OK for Maria to upload an avatar like this to Second Life?

02. If Maria is the owner of celebrity's intellectual property rights or is authorized by the rights owner.

Using some 3D modeling software, Cathy created a model of a car. It took her weeks to make the model and now she wants to sell copies of the car in Second Life. Cathy uploaded the car as a mesh to Second Life then listed it for sale on the Second Life Marketplace. The text of Cathy's listing says "looks like a Mercedes." Is this OK?

03. NO

David is an avid sports fan and wants to share his enthusiasm with other Second Life Residents. David uploaded a large mesh helmet with his favorite team's logo on it. David decorated the outside of his Second Life home with the helmet. When is it OK for David to use his favorite team's logo in Second Life?

04. He cannot use the logo in Second Life.

Tom purchased a membership to a website that offers creative works, such as 3D models, to its members. The terms of use on the website state that the 3D models cannot be sold "as is" but they can be re-sold if they are added to an original creation. Can Tom upload the 3D models as meshes to Second Life and then sell them "as is" to other builders on the Second Life Marketplace?

05. NO

Jill is a popular fashion designer in Second Life. She has created a line of mesh purses and shoes and wants to call her new brand "N1ke". Is this OK?

06. NO

Darlene sells full permission mesh pillars, archways, and roof tops for other residents to use in their Second Life buildings. Darlene includes a notecard with the items. The notecard states that the items can only be re-sold as part of an original creation and are not to be re-sold as standalone items. Sally purchased the mesh objects from Darlene and wants to resell them. Sally can...

07. Include the mesh objects in the prefab houses that she creates, then sell the houses.

Using some 3d modeling tools Becky created some cute little teddy bears which she later uploaded as meshes to Second Life. The teddy bears, when clicked, play a selection of well known romantic songs that Becky does not have permission to use. Is this OK?

08. NO

Linden Lab removed Barbara's meshes or other Second Life content but did not remove other similar content. This could be because...

09. Linden Lab has not discovered or been notified by a rights owner about similar content.

When uploading mesh or creating other content for Second Life, which of the following is important to do if you want to respect intellectual property rights like copyrights, trademarks, and celebrity rights?

10. All of the above.

You scored 10 correct out of 10 questions for a score of 100 percent.