Rue Du Fric

_ For my english readers, you’re out of luck, this is a french-only post because it’s about a french online game : Rue Du Fric (can be translated to “street of money”, or maybe “street of gold”). But you can still have a look at the game if you’re interested. _ Le jeu Rue Du Fric développé par la jeune startup BeeMoov est un jeu 100% javascript + AJAX. Il est très bien fini, il repose un univers extensible “à l’infini” au fur et à mesure de l’arrivée de nouveaux joueurs et l’occupation des sols. Vous pouvez acheter du terrain, placer des maisons dessus, gagner de l’argent, vendre et acheter des biens aux membres ou aux enchères, emprunter de l’argent à la banque et tout ça en interagissant en continu avec les autres. ...

February 16, 2010 · Florent Clairambault

Dirty WordPress APC caching

One or two weeks ago, I made a simple AB benchmarking test on a PHP site I built, it was ok. Then I did the same test on this blog and well… It was freaking slow… On 100 pages with 10 concurrent access, it took 3.5 to 10s to render. Well, I thought I should remove all these plugins I installed to make me and my blog famous (they didn’t perform well). It reduced the generation time by something like 100 ms. ...

February 13, 2010 · Florent Clairambault

WordPress with APC

I updated APC from 3.0 to 3.1 because it totally locked my webserver, it was making it accept HTTP connection but never give any reply. I had some problem accessing the WordPress 3.0 (latest SVN version) admin interface after that upgrade : Fatal error: Call to undefined function wp_dashboard_setup() in /home/sites/clairambault.fr/florent/wp-admin/index.php on line 15 the bad line is : require_once(ABSPATH . 'wp-admin/includes/dashboard.php'); I just found out here it was because I activated APC with the “apc.include_once_override” option set to 1. If you encounter the same problem, just set it to 0 or change the include by something without the ABSPATH constant like for instance : ...

February 12, 2010 · Florent Clairambault

Add a circle overlay to Google Maps API v3

There’s a better alternative : // This file adds a new circle overlay to Google Maps v3 // Original Google Maps API v2 File : http://dawsdesign.com/drupal/google_maps_circle_overlay // Ported to GMaps v3 by http://florent.clairambault.fr/ /** * Filled circle overlay */ var MapCircleOverlay = function(center, radius, strokeWeight, strokeColor, strokeOpacity, fillColor, fillOpacity) { this.center = center; this.radius = radius; this.strokeWeight = strokeWeight; this.strokeColor = strokeColor; this.strokeOpacity = strokeOpacity; this.fillColor = fillColor; this.fillOpacity = fillOpacity; this.circlePolygon = null; // 50 lines look like a pretty good circle this.numPoints = 50; this.d2r = Math.PI / 180; this.bound = null; this.setCenter = function( latLng ) { this.center = latLng; this.draw(); }; this.setRadius = function( radius ) { this.radius = radius; this.draw(); }; }; /* base class overloads follow this comment */ MapCircleOverlay.prototype = new google.maps.OverlayView; // Calculate all the points and draw them // Base method must be implemented like this MapCircleOverlay.prototype.draw = function() { if ( ! isFinite( this.radius ) || ! isFinite( this.center.lat() ) || ! isFinite( this.center.lng() ) ) { if ( console != undefined ) console.error('Radius has to be a number !'); return; } circleLatLngs = new Array(); // Remove the "* 0.621371192" to use miles instead of kilometers var circleLat = this.radius * 0.621371192 * 0.014483; // Convert statute into miles and miles into degrees latitude var circleLng = circleLat / Math.cos( this.center.lat() * this.d2r); // 2PI = 360 degrees, +1 so that the end points meet for (var i = ; i < this.numPoints+1; i++) { var theta = Math.PI * (i / (this.numPoints / 2)); var vertexLat = this.center.lat() + (circleLat * Math.sin(theta)); var vertexLng = this.center.lng() + (circleLng * Math.cos(theta)); var vertextLatLng = new google.maps.LatLng(vertexLat, vertexLng); circleLatLngs.push( vertextLatLng ); } // Before drawing the new polygon, we have to remove the old one this.clear(); this.circlePolygon = new google.maps.Polygon({ paths: circleLatLngs, strokeColor: this.strokeColor, strokeOpacity: this.strokeOpacity, strokeWeight: this.strokeWeight, fillColor: this.fillColor, fillOpacity: this.fillOpacity }); this.circlePolygon.setMap( this.map ); }; MapCircleOverlay.prototype.clear = function() { if ( this.circlePolygon != null ) { this.circlePolygon.setMap( null ); this.circlePolygon = null; } }; MapCircleOverlay.prototype.onRemove = function() { this.clear(); }; <div id="map_canvas" style="width:100%; height:100%"></div> <script type="text/javascript"> // We load the map var latlng = new google.maps.LatLng(-34.397, 150.644); var myOptions = { zoom: 8, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP }; var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); // We load the circle var circle = new MapCircleOverlay( latlng.getPosition(), 10, "#FF0000", 0.8, 3, "#FF0000", 0.35 ); // And we attach it to the map circle.setMap( map ); </script> map.fitBounds( circle.getBounds() );

February 9, 2010 · Florent Clairambault

Redirect port on Linux

Sometimes, you just need to redirect a port on Linux. The solution I could find is to add an entry into xinetd. Here is a sample /etc/xinetd.d file I have, it just redirects the 587 (tcp) port to the 993 port of gmail’s servers. I have to do this because Virgin Mobile France blocks the 993 tcp port. If you’re in the same situation, you can use my server to access you gmail IMAP access. You just have to set the server name to “webingenia.com” and the port to “587”. ...

February 8, 2010 · Florent Clairambault

WordPress supports MultiSites

WordPress now supports MultiSites with its 3.0 version. It’s the current SVN development version. This means you can have one wordpress install for multiple sites. You can see how it works by looking into ms-settings.php. This is quite a good news for anyone willing to manage a community of bloggers. Here is a part of the wp-includes/wp-settings.php file : function wpmu_current_site() { global $wpdb, $current_site, $domain, $path, $sites; if( defined( 'DOMAIN_CURRENT_SITE' ) && defined( 'PATH_CURRENT_SITE' ) ) { $current_site->id = (defined( 'SITE_ID_CURRENT_SITE' ) ? constant('SITE_ID_CURRENT_SITE') : 1); $current_site->domain = DOMAIN_CURRENT_SITE; $current_site->path = $path = PATH_CURRENT_SITE; if( defined( 'BLOGID_CURRENT_SITE' ) ) $current_site->blog_id = BLOGID_CURRENT_SITE; return $current_site; } $current_site = wp_cache_get( "current_site", "site-options" ); if( $current_site ) return $current_site; $wpdb->suppress_errors(); $sites = $wpdb->get_results( "SELECT * FROM $wpdb->site" ); // usually only one site if( count( $sites ) == 1 ) { $current_site = $sites[]; $path = $current_site->path; $current_site->blog_id = $wpdb->get_var( "SELECT blog_id FROM {$wpdb->blogs} WHERE domain='{$current_site->domain}' AND path='{$current_site->path}'" ); $current_site = get_current_site_name( $current_site ); wp_cache_set( "current_site", $current_site, "site-options" ); return $current_site; } $path = substr( $_SERVER[ 'REQUEST_URI' ], , 1 + strpos( $_SERVER[ 'REQUEST_URI' ], '/', 1 ) ); if( is_subdomain_install() ) { $current_site = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->site WHERE domain = %s AND path = %s", $domain, $path) ); if( $current_site != null ) return $current_site; $current_site = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->site WHERE domain = %s AND path='/'", $domain) ); if( $current_site != null ) { $path = '/'; return $current_site; } $sitedomain = substr( $domain, 1 + strpos( $domain, '.' ) ); $current_site = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->site WHERE domain = %s AND path = %s", $sitedomain, $path) ); if( $current_site != null ) return $current_site; $current_site = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->site WHERE domain = %s AND path='/'", $sitedomain) ); if( $current_site == null && defined( "WP_INSTALLING" ) == false ) { if( count( $sites ) == 1 ) { $current_site = $sites[]; die( "That blog does not exist. Please try <a href='http://{$current_site->domain}{$current_site->path}'>http://{$current_site->domain}{$current_site->path}</a>" ); } else { die( "No WPMU site defined on this host. If you are the owner of this site, please check <a href='http://codex.wordpress.org/Debugging_WPMU'>Debugging WPMU</a> for f urther assistance." ); } } else { $path = '/'; } } else { $current_site = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->site WHERE domain = %s AND path = %s", $domain, $path) ); if( $current_site != null ) return $current_site; $current_site = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->site WHERE domain = %s AND path='/'", $domain) ); if( $current_site == null && defined( "WP_INSTALLING" ) == false ) { if( count( $sites ) == 1 ) { $current_site = $sites[]; die( "That blog does not exist. Please try <a href='http://{$current_site->domain}{$current_site->path}'>http://{$current_site->domain}{$current_site->path}</a>" ); } else { die( "No WPMU site defined on this host. If you are the owner of this site, please check <a href='http://codex.wordpress.org/Debugging_WPMU'>Debugging WPMU</a> for f urther assistance." ); } } else { $path = '/'; } } return $current_site; }

January 10, 2010 · Florent Clairambault

ANTS Memory Profiler

Well, I’m speaking about a commercial product again. This time it’s about ANTS Memory Profiler (by Red Gate software, the ones that made .Net reflector). This product will help you identify any .Net memory leak you could have. The truth is, .Net never leaks but you can sometimes make stupid conception mistakes, like forgetting to remove references of some objects (that may contains heavy references themselves). The tool allows you to take snapshots of your running application and compare different snapshots. You can see the difference of memory consumption by some objets or the difference of class instance count. ...

December 30, 2009 · Florent Clairambault

Mono Tools for Visual Studio

I talked about this earlier. The mono tools for Visual Studio is a commercial product that easily enables you to test and port your Windows applications to mono. As I told before this is really a great idea. Because I think Visual Studio is the best IDE and Linux is the best server OS (in my opinion, it’s more efficient and more robust than Windows Server). So, I think it’s the perfect gateway between this two very different (but very close since Mono appeared) environments to achieve greatness. ...

December 29, 2009 · Florent Clairambault

Sharepoint 2010 on my Windows 7

I finally took the time to make “Sharepoint 2010” work on my PC. I previously did the installation as recommended by the Microsoft. I had to do one additionnal thing to make it work : “Desactivate the .Net 4 ISAPI filter”. In the event logs, I had this error: ISAPI Filter 'C:\Windows\Microsoft.NET\Framework\v4.0.21006\aspnet_filter.dll' could not be loaded due to a configuration problem. The current configuration only supports loading images built for a AMD64 processor architecture. The data field contains the error number. To learn more about this issue, including how to troubleshooting this kind of processor architecture mismatch error, see http://go.microsoft.com/fwlink/?LinkId=29349. And then: ...

December 20, 2009 · Florent Clairambault

JObexFTP from Ricardo Schmidt

WARNING: All the Cinterion related content from this blog will be removed to go to the javacint wiki soon. Please get used to going there. Ricardo Schmidt made a great multi-platform TC65 control and file management tool called JOBextFTP. This can be used for anyone whose Module Exchange Suite (MES) doesn’t work or doesn’t work correctly. ...

December 19, 2009 · Florent Clairambault