Added the Level System.
The .bat files now exit upon encountering an error. Post, bigpost, megapost, and topic stats are now tracked for each user. Added the bigpost_min_chars and megapost_min_chars settings. Probably needs to be renamed. Added the Levels test. Run `go test -run "Levels"` The installer now validates the inputted server port. Added a word counter utility function. The template engine now borks less on variable nodes. Added the lt, gt, ge, eq and ne to the template engine. I'm fairly sure eq was already in there, but things get handled differently depending on what type of node it is. Eliminated more "success" variables by converting the errors over into InternalError() and LocalErrors()
This commit is contained in:
parent
7f8aaedb0a
commit
b7c89fd020
|
@ -4,7 +4,7 @@ A super fast forum software written in Go.
|
|||
|
||||
The initial code-base was forked from one of my side projects, but has now gone far beyond that.
|
||||
|
||||
Discord Server: https://discord.gg/eyYvtTf
|
||||
Azareal's Discord Chat: https://discord.gg/eyYvtTf
|
||||
|
||||
If you like this software, please give it a star and give us some feedback :)
|
||||
|
||||
|
|
10
build.bat
10
build.bat
|
@ -1,3 +1,13 @@
|
|||
@echo off
|
||||
go build
|
||||
if %errorlevel% neq 0 (
|
||||
pause
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
go build ./install
|
||||
if %errorlevel% neq 0 (
|
||||
pause
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
echo Gosora was successfully built
|
||||
pause
|
28
data.sql
28
data.sql
|
@ -2,19 +2,25 @@ CREATE TABLE `users`(
|
|||
`uid` int not null AUTO_INCREMENT,
|
||||
`name` varchar(100) not null,
|
||||
`password` varchar(100) not null,
|
||||
`salt` varchar(80) DEFAULT '' not null,
|
||||
`salt` varchar(80) default '' not null,
|
||||
`group` int not null,
|
||||
`active` tinyint DEFAULT 0 not null,
|
||||
`active` tinyint default 0 not null,
|
||||
`is_super_admin` tinyint(1) not null,
|
||||
`createdAt` datetime not null,
|
||||
`lastActiveAt` datetime not null,
|
||||
`session` varchar(200) DEFAULT '' not null,
|
||||
`last_ip` varchar(200) DEFAULT '0.0.0.0.0' not null,
|
||||
`email` varchar(200) DEFAULT '' not null,
|
||||
`avatar` varchar(20) DEFAULT '' not null,
|
||||
`session` varchar(200) default '' not null,
|
||||
`last_ip` varchar(200) default '0.0.0.0.0' not null,
|
||||
`email` varchar(200) default '' not null,
|
||||
`avatar` varchar(20) default '' not null,
|
||||
`message` text not null,
|
||||
`url_prefix` varchar(20) DEFAULT '' not null,
|
||||
`url_name` varchar(100) DEFAULT '' not null,
|
||||
`url_prefix` varchar(20) default '' not null,
|
||||
`url_name` varchar(100) default '' not null,
|
||||
`level` tinyint default 0 not null,
|
||||
`score` int default 0 not null,
|
||||
`posts` int default 0 not null,
|
||||
`bigposts` int default 0 not null,
|
||||
`megaposts` int default 0 not null,
|
||||
`topics` int default 0 not null,
|
||||
primary key(`uid`),
|
||||
unique(`name`)
|
||||
) CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
|
@ -91,8 +97,8 @@ CREATE TABLE `users_replies`(
|
|||
) CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
|
||||
CREATE TABLE `likes`(
|
||||
`weight` int DEFAULT 1 not null,
|
||||
`type` int not null, /* Regular Post = 1, Big Post = 2, Mega Post = 3, etc.*/
|
||||
`weight` tinyint DEFAULT 1 not null,
|
||||
`type` tinyint not null, /* Regular Post = 1, Big Post = 2, Mega Post = 3, etc.*/
|
||||
`targetItem` int not null,
|
||||
`sentBy` int not null,
|
||||
`recalc` tinyint DEFAULT 0 not null
|
||||
|
@ -120,6 +126,8 @@ CREATE TABLE `themes`(
|
|||
|
||||
INSERT INTO settings(`name`,`content`,`type`) VALUES ('url_tags','1','bool');
|
||||
INSERT INTO settings(`name`,`content`,`type`,`constraints`) VALUES ('activation_type','1','list','1-3');
|
||||
INSERT INTO settings(`name`,`content`,`type`) VALUES ('bigpost_min_chars','250','int');
|
||||
INSERT INTO settings(`name`,`content`,`type`) VALUES ('megapost_min_chars','1000','int');
|
||||
INSERT INTO themes(`uname`,`default`) VALUES ('tempra-simple',1);
|
||||
|
||||
INSERT INTO users(`name`,`password`,`email`,`group`,`is_super_admin`,`createdAt`,`lastActiveAt`,`message`)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
import "log"
|
||||
import "bytes"
|
||||
import "strconv"
|
||||
import "math/rand"
|
||||
import "testing"
|
||||
import "net/http"
|
||||
|
@ -12,24 +13,24 @@ import "html/template"
|
|||
func BenchmarkTopicTemplate(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
|
||||
user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","",""}
|
||||
admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","",""}
|
||||
user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0}
|
||||
admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","","",-1,58}
|
||||
var noticeList map[int]string = make(map[int]string)
|
||||
noticeList[0] = "test"
|
||||
|
||||
topic := TopicUser{0,"Lol",template.HTML("Hey everyone!"),0,false,false,"",0,"","","",no_css_tmpl,0,"","","",""}
|
||||
topic := TopicUser{Title: "Lol",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58}
|
||||
|
||||
var replyList []Reply
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0})
|
||||
|
||||
tpage := TopicPage{"Topic Blah",user,noticeList,replyList,topic,false}
|
||||
tpage2 := TopicPage{"Topic Blah",admin,noticeList,replyList,topic,false}
|
||||
|
@ -60,22 +61,22 @@ func BenchmarkTopicTemplate(b *testing.B) {
|
|||
func BenchmarkTopicsTemplate(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
|
||||
user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","",""}
|
||||
admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","",""}
|
||||
user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0}
|
||||
admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","","",-1,58}
|
||||
var noticeList map[int]string = make(map[int]string)
|
||||
noticeList[0] = "test"
|
||||
|
||||
var topicList []TopicUser
|
||||
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
|
||||
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
|
||||
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
|
||||
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
|
||||
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
|
||||
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
|
||||
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
|
||||
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
|
||||
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
|
||||
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58})
|
||||
|
||||
tpage := TopicsPage{"Topic Blah",user,noticeList,topicList,0}
|
||||
tpage2 := TopicsPage{"Topic Blah",admin,noticeList,topicList,0}
|
||||
|
@ -895,6 +896,14 @@ func BenchmarkBBCodePluginWithFullParser(b *testing.B) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestLevels(t *testing.T) {
|
||||
levels := getLevels(40)
|
||||
for level, score := range levels {
|
||||
sscore := strconv.FormatFloat(score, 'f', -1, 64)
|
||||
log.Print("Level: " + strconv.Itoa(level) + " Score: " + sscore)
|
||||
}
|
||||
}
|
||||
|
||||
/*func TestRoute(t *testing.T) {
|
||||
|
||||
}*/
|
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
Binary file not shown.
After Width: | Height: | Size: 334 KiB |
20
install.bat
20
install.bat
|
@ -1,5 +1,25 @@
|
|||
@echo off
|
||||
echo Installing the dependencies
|
||||
go get -u github.com/go-sql-driver/mysql
|
||||
if %errorlevel% neq 0 (
|
||||
pause
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
go get -u golang.org/x/crypto/bcrypt
|
||||
if %errorlevel% neq 0 (
|
||||
pause
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
|
||||
echo Preparing the installer
|
||||
go build
|
||||
if %errorlevel% neq 0 (
|
||||
pause
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
go build ./install
|
||||
if %errorlevel% neq 0 (
|
||||
pause
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
install.exe
|
|
@ -273,6 +273,11 @@ func get_site_details() bool {
|
|||
if server_port == "" {
|
||||
server_port = default_server_port
|
||||
}
|
||||
_, err := strconv.Atoi(server_port)
|
||||
if err != nil {
|
||||
fmt.Println("That's not a valid number!")
|
||||
return false
|
||||
}
|
||||
fmt.Println("Set the server port to " + server_port)
|
||||
return true
|
||||
}
|
||||
|
|
8
main.go
8
main.go
|
@ -41,15 +41,15 @@ var template_profile_handle func(ProfilePage,io.Writer) = nil
|
|||
|
||||
func compile_templates() {
|
||||
var c CTemplateSet
|
||||
user := User{62,"","compiler@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","",""}
|
||||
user := User{62,"","compiler@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0}
|
||||
var noticeList map[int]string = make(map[int]string)
|
||||
noticeList[0] = "test"
|
||||
|
||||
log.Print("Compiling the templates")
|
||||
|
||||
topic := TopicUser{1,"Blah",template.HTML("Hey there!"),0,false,false,"",0,"","","",no_css_tmpl,0,"","","",""}
|
||||
topic := TopicUser{1,"Blah",template.HTML("Hey there!"),0,false,false,"",0,"","","",no_css_tmpl,0,"","","","",58}
|
||||
var replyList []Reply
|
||||
replyList = append(replyList, Reply{0,0,"",template.HTML("Yo!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
|
||||
replyList = append(replyList, Reply{0,0,"",template.HTML("Yo!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0})
|
||||
|
||||
var varList map[string]VarItem = make(map[string]VarItem)
|
||||
tpage := TopicPage{"Title",user,noticeList,replyList,topic,false}
|
||||
|
@ -71,7 +71,7 @@ func compile_templates() {
|
|||
forums_tmpl := c.compile_template("forums.html","templates/","ForumsPage", forums_page, varList)
|
||||
|
||||
var topicList []TopicUser
|
||||
topicList = append(topicList, TopicUser{1,"Topic Title","The topic content.",1,false,false,"",1,"open","Admin","","",0,"","","",""})
|
||||
topicList = append(topicList, TopicUser{1,"Topic Title","The topic content.",1,false,false,"",1,"open","Admin","","",0,"","","","",58})
|
||||
topics_page := TopicsPage{"Topic List",user,noticeList,topicList,""}
|
||||
topics_tmpl := c.compile_template("topics.html","templates/","TopicsPage", topics_page, varList)
|
||||
|
||||
|
|
|
@ -38,11 +38,7 @@ func route_edit_topic(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
topic_name := r.PostFormValue("topic_name")
|
||||
topic_status := r.PostFormValue("topic_status")
|
||||
|
||||
var is_closed bool
|
||||
if topic_status == "closed" {
|
||||
is_closed = true
|
||||
}
|
||||
is_closed := (topic_status == "closed")
|
||||
|
||||
topic_content := html.EscapeString(r.PostFormValue("topic_content"))
|
||||
_, err = edit_topic_stmt.Exec(topic_name, preparse_message(topic_content), parse_message(html.EscapeString(preparse_message(topic_content))), is_closed, tid)
|
||||
|
@ -74,7 +70,9 @@ func route_delete_topic(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
err = db.QueryRow("SELECT tid from topics where tid = ?", tid).Scan(&tid)
|
||||
var content string
|
||||
var createdBy int
|
||||
err = db.QueryRow("select tid, content, createdBy from topics where tid = ?", tid).Scan(&tid, &content, &createdBy)
|
||||
if err == sql.ErrNoRows {
|
||||
LocalError("The topic you tried to delete doesn't exist.",w,r,user)
|
||||
return
|
||||
|
@ -88,9 +86,15 @@ func route_delete_topic(w http.ResponseWriter, r *http.Request) {
|
|||
InternalError(err,w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
log.Print("The topic '" + strconv.Itoa(tid) + "' was deleted by User ID #" + strconv.Itoa(user.ID) + ".")
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
http.Redirect(w,r,"/",http.StatusSeeOther)
|
||||
|
||||
wcount := word_count(content)
|
||||
err = decrease_post_user_stats(wcount, createdBy, true, user)
|
||||
if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func route_stick_topic(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -152,7 +156,6 @@ func route_reply_edit_submit(w http.ResponseWriter, r *http.Request) {
|
|||
LocalError("Bad Form", w, r, user)
|
||||
return
|
||||
}
|
||||
|
||||
is_js := r.PostFormValue("js")
|
||||
if is_js == "" {
|
||||
is_js = "0"
|
||||
|
@ -218,7 +221,9 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
var tid int
|
||||
err = db.QueryRow("SELECT tid from replies where rid = ?", rid).Scan(&tid)
|
||||
var content string
|
||||
var createdBy int
|
||||
err = db.QueryRow("SELECT tid, content, createdBy from replies where rid = ?", rid).Scan(&tid, &content, &createdBy)
|
||||
if err == sql.ErrNoRows {
|
||||
LocalErrorJSQ("The reply you tried to delete doesn't exist.",w,r,user,is_js)
|
||||
return
|
||||
|
@ -233,12 +238,18 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
log.Print("The reply '" + strconv.Itoa(rid) + "' was deleted by User ID #" + strconv.Itoa(user.ID) + ".")
|
||||
|
||||
if is_js == "0" {
|
||||
//http.Redirect(w,r, "/topic/" + strconv.Itoa(tid), http.StatusSeeOther)
|
||||
} else {
|
||||
fmt.Fprintf(w,"{'success': '1'}")
|
||||
}
|
||||
|
||||
wcount := word_count(content)
|
||||
err = decrease_post_user_stats(wcount, createdBy, false, user)
|
||||
if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func route_profile_reply_edit_submit(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
44
mysql.go
44
mysql.go
|
@ -34,6 +34,12 @@ var register_stmt *sql.Stmt
|
|||
var username_exists_stmt *sql.Stmt
|
||||
var change_group_stmt *sql.Stmt
|
||||
var activate_user_stmt *sql.Stmt
|
||||
var update_user_level_stmt *sql.Stmt
|
||||
var increment_user_score_stmt *sql.Stmt
|
||||
var increment_user_posts_stmt *sql.Stmt
|
||||
var increment_user_bigposts_stmt *sql.Stmt
|
||||
var increment_user_megaposts_stmt *sql.Stmt
|
||||
var increment_user_topics_stmt *sql.Stmt
|
||||
var create_profile_reply_stmt *sql.Stmt
|
||||
var edit_profile_reply_stmt *sql.Stmt
|
||||
var delete_profile_reply_stmt *sql.Stmt
|
||||
|
@ -64,7 +70,7 @@ func init_database(err error) {
|
|||
}
|
||||
|
||||
log.Print("Preparing get_session statement.")
|
||||
get_session_stmt, err = db.Prepare("select `uid`, `name`, `group`, `is_super_admin`, `session`, `email`, `avatar`, `message`, `url_prefix`, `url_name` FROM `users` WHERE `uid` = ? AND `session` = ? AND `session` <> ''")
|
||||
get_session_stmt, err = db.Prepare("select `uid`, `name`, `group`, `is_super_admin`, `session`, `email`, `avatar`, `message`, `url_prefix`, `url_name`, `level`, `score` FROM `users` where `uid` = ? AND `session` = ? AND `session` <> ''")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -222,6 +228,42 @@ func init_database(err error) {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Print("Preparing update_user_level statement.")
|
||||
update_user_level_stmt, err = db.Prepare("UPDATE users SET level = ? WHERE uid = ?")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Print("Preparing increment_user_score statement.")
|
||||
increment_user_score_stmt, err = db.Prepare("UPDATE users SET score = score + ? WHERE uid = ?")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Print("Preparing increment_user_posts statement.")
|
||||
increment_user_posts_stmt, err = db.Prepare("UPDATE users SET posts = posts + ? WHERE uid = ?")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Print("Preparing increment_user_bigposts statement.")
|
||||
increment_user_bigposts_stmt, err = db.Prepare("UPDATE users SET posts = posts + ?, bigposts = bigposts + ? WHERE uid = ?")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Print("Preparing increment_user_megaposts statement.")
|
||||
increment_user_megaposts_stmt, err = db.Prepare("UPDATE users SET posts = posts + ?, bigposts = bigposts + ?, megaposts = megaposts + ? WHERE uid = ?")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Print("Preparing increment_user_topics statement.")
|
||||
increment_user_topics_stmt, err = db.Prepare("UPDATE users SET topics = topics + ? WHERE uid = ?")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Print("Preparing create_profile_reply statement.")
|
||||
create_profile_reply_stmt, err = db.Prepare("INSERT INTO users_replies(uid,content,parsed_content,createdAt,createdBy) VALUES(?,?,?,NOW(),?)")
|
||||
if err != nil {
|
||||
|
|
1
reply.go
1
reply.go
|
@ -20,4 +20,5 @@ type Reply struct
|
|||
URL string
|
||||
URLPrefix string
|
||||
URLName string
|
||||
Level int
|
||||
}
|
||||
|
|
230
routes.go
230
routes.go
|
@ -236,7 +236,6 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
|
|||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
var(
|
||||
err error
|
||||
rid int
|
||||
|
@ -254,13 +253,14 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
|
|||
replyURL string
|
||||
replyURLPrefix string
|
||||
replyURLName string
|
||||
replyLevel int
|
||||
is_super_admin bool
|
||||
group int
|
||||
|
||||
replyList []Reply
|
||||
)
|
||||
|
||||
topic := TopicUser{0,"","",0,false,false,"",0,"","","",no_css_tmpl,0,"","","",""}
|
||||
topic := TopicUser{Css: no_css_tmpl}
|
||||
topic.ID, err = strconv.Atoi(r.URL.Path[len("/topic/"):])
|
||||
if err != nil {
|
||||
LocalError("The provided TopicID is not a valid number.",w,r,user)
|
||||
|
@ -274,7 +274,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
|
|||
}
|
||||
|
||||
// Get the topic..
|
||||
err = db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, users.name, users.avatar, users.is_super_admin, users.group, users.url_prefix, users.url_name from topics left join users ON topics.createdBy = users.uid where tid = ?", topic.ID).Scan(&topic.Title, &content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.CreatedByName, &topic.Avatar, &is_super_admin, &group, &topic.URLPrefix, &topic.URLName)
|
||||
err = db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, users.name, users.avatar, users.is_super_admin, users.group, users.url_prefix, users.url_name, users.level from topics left join users ON topics.createdBy = users.uid where tid = ?", topic.ID).Scan(&topic.Title, &content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.CreatedByName, &topic.Avatar, &is_super_admin, &group, &topic.URLPrefix, &topic.URLName, &topic.Level)
|
||||
if err == sql.ErrNoRows {
|
||||
NotFound(w,r,user)
|
||||
return
|
||||
|
@ -300,12 +300,13 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
|
|||
}
|
||||
if is_super_admin || groups[group].Is_Mod || groups[group].Is_Admin {
|
||||
topic.Css = staff_css_tmpl
|
||||
topic.Level = -1
|
||||
}
|
||||
if groups[group].Tag != "" {
|
||||
//if groups[group].Tag != "" {
|
||||
topic.Tag = groups[group].Tag
|
||||
} else {
|
||||
topic.Tag = ""
|
||||
}
|
||||
//} else {
|
||||
// topic.Tag = ""
|
||||
//}
|
||||
if settings["url_tags"] == false {
|
||||
topic.URLName = ""
|
||||
} else {
|
||||
|
@ -318,7 +319,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
|
|||
}
|
||||
|
||||
// Get the replies..
|
||||
rows, err := db.Query("select replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.is_super_admin, users.group, users.url_prefix, users.url_name from replies left join users ON replies.createdBy = users.uid where tid = ?", topic.ID)
|
||||
rows, err := db.Query("select replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.is_super_admin, users.group, users.url_prefix, users.url_name, users.level from replies left join users ON replies.createdBy = users.uid where tid = ?", topic.ID)
|
||||
if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
return
|
||||
|
@ -326,7 +327,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
|
|||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
err := rows.Scan(&rid, &replyContent, &replyCreatedBy, &replyCreatedAt, &replyLastEdit, &replyLastEditBy, &replyAvatar, &replyCreatedByName, &is_super_admin, &group, &replyURLPrefix, &replyURLName)
|
||||
err := rows.Scan(&rid, &replyContent, &replyCreatedBy, &replyCreatedAt, &replyLastEdit, &replyLastEditBy, &replyAvatar, &replyCreatedByName, &is_super_admin, &group, &replyURLPrefix, &replyURLName, &replyLevel)
|
||||
if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
return
|
||||
|
@ -335,6 +336,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
|
|||
replyLines = strings.Count(replyContent,"\n")
|
||||
if is_super_admin || groups[group].Is_Mod || groups[group].Is_Admin {
|
||||
replyCss = staff_css_tmpl
|
||||
replyLevel = -1
|
||||
} else {
|
||||
replyCss = no_css_tmpl
|
||||
}
|
||||
|
@ -345,11 +347,11 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
|
|||
} else {
|
||||
replyAvatar = strings.Replace(noavatar,"{id}",strconv.Itoa(replyCreatedBy),1)
|
||||
}
|
||||
if groups[group].Tag != "" {
|
||||
//if groups[group].Tag != "" {
|
||||
replyTag = groups[group].Tag
|
||||
} else {
|
||||
replyTag = ""
|
||||
}
|
||||
//} else {
|
||||
// replyTag = ""
|
||||
//}
|
||||
if settings["url_tags"] == false {
|
||||
replyURLName = ""
|
||||
} else {
|
||||
|
@ -361,7 +363,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
|
|||
}
|
||||
}
|
||||
|
||||
replyItem := Reply{rid,topic.ID,replyContent,template.HTML(parse_message(replyContent)),replyCreatedBy,replyCreatedByName,replyCreatedAt,replyLastEdit,replyLastEditBy,replyAvatar,replyCss,replyLines,replyTag,replyURL,replyURLPrefix,replyURLName}
|
||||
replyItem := Reply{rid,topic.ID,replyContent,template.HTML(parse_message(replyContent)),replyCreatedBy,replyCreatedByName,replyCreatedAt,replyLastEdit,replyLastEditBy,replyAvatar,replyCss,replyLines,replyTag,replyURL,replyURLPrefix,replyURLName,replyLevel}
|
||||
|
||||
if hooks["rrow_assign"] != nil {
|
||||
replyItem = run_hook("rrow_assign", replyItem).(Reply)
|
||||
|
@ -422,7 +424,7 @@ func route_profile(w http.ResponseWriter, r *http.Request){
|
|||
puser = user
|
||||
} else {
|
||||
// Fetch the user data
|
||||
err = db.QueryRow("SELECT `name`, `group`, `is_super_admin`, `avatar`, `message`, `url_prefix`, `url_name` FROM `users` WHERE `uid` = ?", puser.ID).Scan(&puser.Name, &puser.Group, &puser.Is_Super_Admin, &puser.Avatar, &puser.Message, &puser.URLPrefix, &puser.URLName)
|
||||
err = db.QueryRow("SELECT `name`, `group`, `is_super_admin`, `avatar`, `message`, `url_prefix`, `url_name`, `level` FROM `users` WHERE `uid` = ?", puser.ID).Scan(&puser.Name, &puser.Group, &puser.Is_Super_Admin, &puser.Avatar, &puser.Message, &puser.URLPrefix, &puser.URLName, &puser.Level)
|
||||
if err == sql.ErrNoRows {
|
||||
NotFound(w,r,user)
|
||||
return
|
||||
|
@ -440,11 +442,11 @@ func route_profile(w http.ResponseWriter, r *http.Request){
|
|||
}
|
||||
}
|
||||
|
||||
if groups[puser.Group].Tag != "" {
|
||||
//if groups[puser.Group].Tag != "" {
|
||||
puser.Tag = groups[puser.Group].Tag
|
||||
} else {
|
||||
puser.Tag = ""
|
||||
}
|
||||
//} else {
|
||||
// puser.Tag = ""
|
||||
//}
|
||||
|
||||
if puser.Avatar != "" {
|
||||
if puser.Avatar[0] == '.' {
|
||||
|
@ -490,7 +492,7 @@ func route_profile(w http.ResponseWriter, r *http.Request){
|
|||
replyTag = ""
|
||||
}
|
||||
|
||||
replyList = append(replyList, Reply{rid,puser.ID,replyContent,template.HTML(parse_message(replyContent)),replyCreatedBy,replyCreatedByName,replyCreatedAt,replyLastEdit,replyLastEditBy,replyAvatar,replyCss,replyLines,replyTag,"","",""})
|
||||
replyList = append(replyList, Reply{rid,puser.ID,replyContent,template.HTML(parse_message(replyContent)),replyCreatedBy,replyCreatedByName,replyCreatedAt,replyLastEdit,replyLastEditBy,replyAvatar,replyCss,replyLines,replyTag,"","","",0})
|
||||
}
|
||||
err = rows.Err()
|
||||
if err != nil {
|
||||
|
@ -518,7 +520,6 @@ func route_topic_create(w http.ResponseWriter, r *http.Request){
|
|||
NoPermissions(w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
pi := Page{"Create Topic","create-topic",user,noticeList,tList,0}
|
||||
templates.ExecuteTemplate(w,"create-topic.html", pi)
|
||||
}
|
||||
|
@ -539,38 +540,32 @@ func route_create_topic(w http.ResponseWriter, r *http.Request) {
|
|||
LocalError("Bad Form", w, r, user)
|
||||
return
|
||||
}
|
||||
success := 1
|
||||
topic_name := html.EscapeString(r.PostFormValue("topic-name"))
|
||||
content := html.EscapeString(preparse_message(r.PostFormValue("topic-content")))
|
||||
|
||||
res, err := create_topic_stmt.Exec(topic_name,html.EscapeString(preparse_message(r.PostFormValue("topic-content"))),parse_message(html.EscapeString(preparse_message(r.PostFormValue("topic-content")))),user.ID)
|
||||
res, err := create_topic_stmt.Exec(topic_name,content,parse_message(content),user.ID)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
success = 0
|
||||
InternalError(err,w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
lastId, err := res.LastInsertId()
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
success = 0
|
||||
InternalError(err,w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = update_forum_cache_stmt.Exec(topic_name, lastId, user.Name, user.ID, 1)
|
||||
if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
if success != 1 {
|
||||
errmsg := "Unable to create the topic"
|
||||
pi := Page{"Error","error",user,nList,tList,errmsg}
|
||||
|
||||
var b bytes.Buffer
|
||||
templates.ExecuteTemplate(&b,"error.html", pi)
|
||||
errpage := b.String()
|
||||
w.WriteHeader(500)
|
||||
fmt.Fprintln(w,errpage)
|
||||
} else {
|
||||
http.Redirect(w, r, "/topic/" + strconv.FormatInt(lastId, 10), http.StatusSeeOther)
|
||||
http.Redirect(w, r, "/topic/" + strconv.FormatInt(lastId,10), http.StatusSeeOther)
|
||||
wcount := word_count(content)
|
||||
err = increase_post_user_stats(wcount, user.ID, true, user)
|
||||
if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -589,7 +584,6 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
|
|||
LocalError("Bad Form", w, r, user)
|
||||
return
|
||||
}
|
||||
|
||||
tid, err := strconv.Atoi(r.PostFormValue("tid"))
|
||||
if err != nil {
|
||||
LocalError("Failed to convert the TopicID", w, r, user)
|
||||
|
@ -597,7 +591,7 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
content := preparse_message(html.EscapeString(r.PostFormValue("reply-content")))
|
||||
log.Print(content)
|
||||
//log.Print(content)
|
||||
_, err = create_reply_stmt.Exec(tid,content,parse_message(content),user.ID)
|
||||
if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
|
@ -621,6 +615,12 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
http.Redirect(w, r, "/topic/" + strconv.Itoa(tid), http.StatusSeeOther)
|
||||
wcount := word_count(content)
|
||||
err = increase_post_user_stats(wcount, user.ID, false, user)
|
||||
if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func route_profile_reply_create(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -638,52 +638,29 @@ func route_profile_reply_create(w http.ResponseWriter, r *http.Request) {
|
|||
LocalError("Bad Form", w, r, user)
|
||||
return
|
||||
}
|
||||
|
||||
success := 1
|
||||
uid, err := strconv.Atoi(r.PostFormValue("uid"))
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
success = 0
|
||||
|
||||
errmsg := "Unable to create the reply"
|
||||
pi := Page{"Error","error",user,nList,tList,errmsg}
|
||||
|
||||
var b bytes.Buffer
|
||||
templates.ExecuteTemplate(&b,"error.html", pi)
|
||||
errpage := b.String()
|
||||
w.WriteHeader(500)
|
||||
fmt.Fprintln(w,errpage)
|
||||
LocalError("Invalid UID",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = create_profile_reply_stmt.Exec(uid,html.EscapeString(preparse_message(r.PostFormValue("reply-content"))),parse_message(html.EscapeString(preparse_message(r.PostFormValue("reply-content")))),user.ID)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
success = 0
|
||||
InternalError(err,w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
var user_name string
|
||||
err = db.QueryRow("select name from users where uid = ?", uid).Scan(&user_name)
|
||||
if err == sql.ErrNoRows {
|
||||
log.Print(err)
|
||||
success = 0
|
||||
LocalError("The profile you're trying to post on doesn't exist.",w,r,user)
|
||||
return
|
||||
} else if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
if success != 1 {
|
||||
errmsg := "Unable to create the reply"
|
||||
pi := Page{"Error","error",user,nList,tList,errmsg}
|
||||
|
||||
var b bytes.Buffer
|
||||
templates.ExecuteTemplate(&b,"error.html", pi)
|
||||
errpage := b.String()
|
||||
w.WriteHeader(500)
|
||||
fmt.Fprintln(w,errpage)
|
||||
} else {
|
||||
http.Redirect(w, r, "/user/" + strconv.Itoa(uid), http.StatusSeeOther)
|
||||
}
|
||||
http.Redirect(w, r, "/user/" + strconv.Itoa(uid), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func route_report_submit(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -691,7 +668,6 @@ func route_report_submit(w http.ResponseWriter, r *http.Request) {
|
|||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if !user.Loggedin {
|
||||
LoginRequired(w,r,user)
|
||||
return
|
||||
|
@ -872,13 +848,7 @@ func route_account_own_edit_critical_submit(w http.ResponseWriter, r *http.Reque
|
|||
|
||||
err = get_password_stmt.QueryRow(user.ID).Scan(&real_password, &salt)
|
||||
if err == sql.ErrNoRows {
|
||||
pi := Page{"Error","error",user,nList,tList,"Your account doesn't exist."}
|
||||
|
||||
var b bytes.Buffer
|
||||
templates.ExecuteTemplate(&b,"error.html", pi)
|
||||
errpage := b.String()
|
||||
w.WriteHeader(500)
|
||||
fmt.Fprintln(w,errpage)
|
||||
LocalError("Your account no longer exists.",w,r,user)
|
||||
return
|
||||
} else if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
|
@ -888,26 +858,14 @@ func route_account_own_edit_critical_submit(w http.ResponseWriter, r *http.Reque
|
|||
current_password = current_password + salt
|
||||
err = bcrypt.CompareHashAndPassword([]byte(real_password), []byte(current_password))
|
||||
if err == bcrypt.ErrMismatchedHashAndPassword {
|
||||
pi := Page{"Error","error",user,nList,tList,"That's not the correct password."}
|
||||
|
||||
var b bytes.Buffer
|
||||
templates.ExecuteTemplate(&b,"error.html", pi)
|
||||
errpage := b.String()
|
||||
w.WriteHeader(500)
|
||||
fmt.Fprintln(w,errpage)
|
||||
LocalError("That's not the correct password.",w,r,user)
|
||||
return
|
||||
} else if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
return
|
||||
}
|
||||
if new_password != confirm_password {
|
||||
pi := Page{"Error","error",user,nList,tList,"The two passwords don't match."}
|
||||
|
||||
var b bytes.Buffer
|
||||
templates.ExecuteTemplate(&b,"error.html", pi)
|
||||
errpage := b.String()
|
||||
w.WriteHeader(500)
|
||||
fmt.Fprintln(w,errpage)
|
||||
LocalError("The two passwords don't match.",w,r,user)
|
||||
return
|
||||
}
|
||||
SetPassword(user.ID, new_password)
|
||||
|
@ -1192,16 +1150,8 @@ func route_logout(w http.ResponseWriter, r *http.Request) {
|
|||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if !user.Loggedin {
|
||||
errmsg := "You can't logout without logging in first."
|
||||
pi := Page{"Error","error",user,nList,tList,errmsg}
|
||||
|
||||
var b bytes.Buffer
|
||||
templates.ExecuteTemplate(&b,"error.html", pi)
|
||||
errpage := b.String()
|
||||
w.WriteHeader(500)
|
||||
fmt.Fprintln(w,errpage)
|
||||
LocalError("You can't logout without logging in first.",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1218,19 +1168,10 @@ func route_login(w http.ResponseWriter, r *http.Request) {
|
|||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if user.Loggedin {
|
||||
errmsg := "You're already logged in."
|
||||
pi := Page{"Error","error",user,nList,tList,errmsg}
|
||||
|
||||
var b bytes.Buffer
|
||||
templates.ExecuteTemplate(&b,"error.html", pi)
|
||||
errpage := b.String()
|
||||
w.WriteHeader(500)
|
||||
fmt.Fprintln(w,errpage)
|
||||
LocalError("You're already logged in.",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
pi := Page{"Login","login",user,noticeList,tList,0}
|
||||
templates.ExecuteTemplate(w,"login.html", pi)
|
||||
}
|
||||
|
@ -1240,16 +1181,8 @@ func route_login_submit(w http.ResponseWriter, r *http.Request) {
|
|||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if user.Loggedin {
|
||||
errmsg := "You're already logged in."
|
||||
pi := Page{"Error","error",user,nList,tList,errmsg}
|
||||
|
||||
var b bytes.Buffer
|
||||
templates.ExecuteTemplate(&b,"error.html", pi)
|
||||
errpage := b.String()
|
||||
w.WriteHeader(500)
|
||||
fmt.Fprintln(w,errpage)
|
||||
LocalError("You're already logged in.",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1268,14 +1201,7 @@ func route_login_submit(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
err = login_stmt.QueryRow(username).Scan(&uid, &username, &real_password, &salt)
|
||||
if err == sql.ErrNoRows {
|
||||
errmsg := "That username doesn't exist."
|
||||
pi := Page{"Error","error",user,nList,tList,errmsg}
|
||||
|
||||
var b bytes.Buffer
|
||||
templates.ExecuteTemplate(&b,"error.html", pi)
|
||||
errpage := b.String()
|
||||
w.WriteHeader(500)
|
||||
fmt.Fprintln(w,errpage)
|
||||
LocalError("That username doesn't exist.",w,r,user)
|
||||
return
|
||||
} else if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
|
@ -1285,14 +1211,7 @@ func route_login_submit(w http.ResponseWriter, r *http.Request) {
|
|||
// Emergency password reset mechanism..
|
||||
if salt == "" {
|
||||
if password != real_password {
|
||||
errmsg := "That's not the correct password."
|
||||
pi := Page{"Error","error",user,nList,tList,errmsg}
|
||||
|
||||
var b bytes.Buffer
|
||||
templates.ExecuteTemplate(&b,"error.html", pi)
|
||||
errpage := b.String()
|
||||
w.WriteHeader(500)
|
||||
fmt.Fprintln(w,errpage)
|
||||
LocalError("That's not the correct password.",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1307,14 +1226,7 @@ func route_login_submit(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
err := bcrypt.CompareHashAndPassword([]byte(real_password), []byte(password))
|
||||
if err == bcrypt.ErrMismatchedHashAndPassword {
|
||||
errmsg := "That's not the correct password."
|
||||
pi := Page{"Error","error",user,nList,tList,errmsg}
|
||||
|
||||
var b bytes.Buffer
|
||||
templates.ExecuteTemplate(&b,"error.html", pi)
|
||||
errpage := b.String()
|
||||
w.WriteHeader(500)
|
||||
fmt.Fprintln(w,errpage)
|
||||
LocalError("That's not the correct password.",w,r,user)
|
||||
return
|
||||
} else if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
|
@ -1347,17 +1259,9 @@ func route_register(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
if user.Loggedin {
|
||||
errmsg := "You're already logged in."
|
||||
pi := Page{"Error","error",user,nList,tList,errmsg}
|
||||
|
||||
var b bytes.Buffer
|
||||
templates.ExecuteTemplate(&b,"error.html", pi)
|
||||
errpage := b.String()
|
||||
w.WriteHeader(500)
|
||||
fmt.Fprintln(w,errpage)
|
||||
LocalError("You're already logged in.",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
pi := Page{"Registration","register",user,noticeList,tList,0}
|
||||
templates.ExecuteTemplate(w,"register.html", pi)
|
||||
}
|
||||
|
@ -1367,7 +1271,6 @@ func route_register_submit(w http.ResponseWriter, r *http.Request) {
|
|||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
LocalError("Bad Form", w, r, user)
|
||||
|
@ -1400,14 +1303,7 @@ func route_register_submit(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// Do the two inputted passwords match..?
|
||||
if password != confirm_password {
|
||||
errmsg := "The two passwords don't match."
|
||||
pi := Page{"Password Mismatch","error",user,nList,tList,errmsg}
|
||||
|
||||
var b bytes.Buffer
|
||||
templates.ExecuteTemplate(&b,"error.html", pi)
|
||||
errpage := b.String()
|
||||
w.WriteHeader(500)
|
||||
fmt.Fprintln(w,errpage)
|
||||
LocalError("The two passwords don't match.",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1417,14 +1313,7 @@ func route_register_submit(w http.ResponseWriter, r *http.Request) {
|
|||
InternalError(err,w,r,user)
|
||||
return
|
||||
} else if err != sql.ErrNoRows {
|
||||
errmsg := "This username isn't available. Try another."
|
||||
pi := Page{"Username Taken","error",user,nList,tList,errmsg}
|
||||
|
||||
var b bytes.Buffer
|
||||
templates.ExecuteTemplate(&b,"error.html", pi)
|
||||
errpage := b.String()
|
||||
w.WriteHeader(500)
|
||||
fmt.Fprintln(w,errpage)
|
||||
LocalError("This username isn't available. Try another.",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1433,7 +1322,6 @@ func route_register_submit(w http.ResponseWriter, r *http.Request) {
|
|||
InternalError(err,w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
session, err := GenerateSafeString(sessionLength)
|
||||
if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
|
|
5
run.bat
5
run.bat
|
@ -1,3 +1,8 @@
|
|||
@echo off
|
||||
go build
|
||||
if %errorlevel% neq 0 (
|
||||
pause
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
gosora.exe
|
||||
pause
|
|
@ -1,7 +1,7 @@
|
|||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
||||
package main
|
||||
import "io"
|
||||
import "strconv"
|
||||
import "io"
|
||||
|
||||
func init() {
|
||||
template_profile_handle = template_profile
|
||||
|
|
|
@ -120,10 +120,14 @@ w.Write([]byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128p
|
|||
}
|
||||
w.Write([]byte(`">
|
||||
<p class="hide_on_edit topic_content user_content" style="margin: 0;padding: 0;">` + string(tmpl_topic_vars.Topic.Content.(template.HTML)) + `</p>
|
||||
<textarea name="topic_content" class="show_on_edit topic_content_input">` + string(tmpl_topic_vars.Topic.Content.(template.HTML)) + `</textarea>
|
||||
<br /><br />
|
||||
<textarea name="topic_content" class="show_on_edit topic_content_input">` + string(tmpl_topic_vars.Topic.Content.(template.HTML)) + `</textarea><br /><br />
|
||||
<a href="/user/` + strconv.Itoa(tmpl_topic_vars.Topic.CreatedBy) + `" class="username real_username">` + tmpl_topic_vars.Topic.CreatedByName + `</a>
|
||||
`))
|
||||
if tmpl_topic_vars.Topic.Level != -1 {
|
||||
w.Write([]byte(`<a class="username level hide_on_mobile" title="Level ` + strconv.Itoa(tmpl_topic_vars.Topic.Level) + `">L` + strconv.Itoa(tmpl_topic_vars.Topic.Level) + `</a>`))
|
||||
}
|
||||
w.Write([]byte(`
|
||||
`))
|
||||
if tmpl_topic_vars.Topic.Tag != "" {
|
||||
w.Write([]byte(`<a class="username hide_on_micro" style="float: right;">` + tmpl_topic_vars.Topic.Tag + `</a>`))
|
||||
} else {
|
||||
|
@ -151,6 +155,11 @@ w.Write([]byte(`">
|
|||
<p class="editable_block user_content" style="margin: 0;padding: 0;">` + string(item.ContentHtml) + `</p><br /><br />
|
||||
<a href="/user/` + strconv.Itoa(item.CreatedBy) + `" class="username real_username">` + item.CreatedByName + `</a>
|
||||
`))
|
||||
if item.Level != -1 {
|
||||
w.Write([]byte(`<a class="username level hide_on_mobile" title="Level ` + strconv.Itoa(item.Level) + `">L` + strconv.Itoa(item.Level) + `</a>`))
|
||||
}
|
||||
w.Write([]byte(`
|
||||
`))
|
||||
if tmpl_topic_vars.CurrentUser.Perms.EditReply {
|
||||
w.Write([]byte(`<a href="/reply/edit/submit/` + strconv.Itoa(item.ID) + `" class="mod_button"><button class="username edit_item">Edit</button></a>`))
|
||||
}
|
||||
|
|
21
templates.go
21
templates.go
|
@ -304,7 +304,6 @@ func (c *CTemplateSet) compile_subswitch(varholder string, holdreflect reflect.V
|
|||
} else {
|
||||
varbit += "." + id
|
||||
}
|
||||
|
||||
if debug {
|
||||
fmt.Println("End Cycle")
|
||||
}
|
||||
|
@ -331,9 +330,8 @@ func (c *CTemplateSet) compile_subswitch(varholder string, holdreflect reflect.V
|
|||
fmt.Println(n.String())
|
||||
fmt.Println(n.Ident)
|
||||
}
|
||||
|
||||
out, _ = c.compile_if_varsub(n.String(), varholder, template_name, holdreflect)
|
||||
return "w.Write([]byte(" + out + "))\n"
|
||||
varname, reflectVal := c.compile_if_varsub(n.String(), varholder, template_name, holdreflect)
|
||||
return c.compile_varsub(varname, reflectVal)
|
||||
case *parse.StringNode:
|
||||
return n.Quoted
|
||||
default:
|
||||
|
@ -429,6 +427,21 @@ func (c *CTemplateSet) compile_identswitch(varholder string, holdreflect reflect
|
|||
case "le":
|
||||
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " <= " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
|
||||
break ArgLoop
|
||||
case "lt":
|
||||
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " < " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
|
||||
break ArgLoop
|
||||
case "gt":
|
||||
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " > " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
|
||||
break ArgLoop
|
||||
case "ge":
|
||||
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " >= " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
|
||||
break ArgLoop
|
||||
case "eq":
|
||||
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " == " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
|
||||
break ArgLoop
|
||||
case "ne":
|
||||
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " != " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
|
||||
break ArgLoop
|
||||
default:
|
||||
if debug {
|
||||
fmt.Println("Variable!")
|
||||
|
|
|
@ -23,9 +23,9 @@
|
|||
<div class="rowblock post_container">
|
||||
<div class="rowitem passive editable_parent post_item" style="border-bottom: none;{{ if .Topic.Avatar }}background-image: url({{ .Topic.Avatar }}), url(/static/white-dot.jpg);background-position: 0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;{{.Topic.Css}}{{end}}">
|
||||
<p class="hide_on_edit topic_content user_content" style="margin: 0;padding: 0;">{{.Topic.Content}}</p>
|
||||
<textarea name="topic_content" class="show_on_edit topic_content_input">{{.Topic.Content}}</textarea>
|
||||
<br /><br />
|
||||
<textarea name="topic_content" class="show_on_edit topic_content_input">{{.Topic.Content}}</textarea><br /><br />
|
||||
<a href="/user/{{.Topic.CreatedBy}}" class="username real_username">{{.Topic.CreatedByName}}</a>
|
||||
{{if ne .Topic.Level -1}}<a class="username level hide_on_mobile" title="Level {{.Topic.Level}}">L{{.Topic.Level}}</a>{{end}}
|
||||
{{if .Topic.Tag}}<a class="username hide_on_micro" style="float: right;">{{.Topic.Tag}}</a>{{else if .Topic.URLName}}<a href="{{.Topic.URL}}" class="username" style="color: #505050;float: right;">{{.Topic.URLName}}</a>
|
||||
<a class="username" style="color: #505050;float: right;border-right: 0;">{{.Topic.URLPrefix}}</a>{{end}}
|
||||
</div>
|
||||
|
@ -34,6 +34,7 @@
|
|||
<div class="rowitem rowhead passive deletable_block editable_parent post_item" style="{{ if .Avatar }}background-image: url({{.Avatar}}), url(/static/white-dot.jpg);background-position: 0px {{if le .ContentLines 5}}-1{{end}}0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;{{.Css}}{{end}}">
|
||||
<p class="editable_block user_content" style="margin: 0;padding: 0;">{{.ContentHtml}}</p><br /><br />
|
||||
<a href="/user/{{.CreatedBy}}" class="username real_username">{{.CreatedByName}}</a>
|
||||
{{if ne .Level -1}}<a class="username level hide_on_mobile" title="Level {{.Level}}">L{{.Level}}</a>{{end}}
|
||||
{{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}" class="mod_button"><button class="username edit_item">Edit</button></a>{{end}}
|
||||
{{if $.CurrentUser.Perms.DeleteReply}}<a href="/reply/delete/submit/{{.ID}}" class="mod_button"><button class="username delete_item">Delete</button></a>{{end}}
|
||||
<a href="/report/submit/{{.ID}}?session={{$.CurrentUser.Session}}&type=reply" class="mod_button"><button class="username report_item">Report</button></a>
|
||||
|
|
1
topic.go
1
topic.go
|
@ -34,4 +34,5 @@ type TopicUser struct
|
|||
URL string
|
||||
URLPrefix string
|
||||
URLName string
|
||||
Level int
|
||||
}
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
@echo off
|
||||
go get -u github.com/go-sql-driver/mysql
|
||||
if %errorlevel% neq 0 (
|
||||
pause
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
go get -u golang.org/x/crypto/bcrypt
|
||||
if %errorlevel% neq 0 (
|
||||
pause
|
||||
exit /b %errorlevel%
|
||||
)
|
||||
echo The dependencies were successfully updated
|
||||
pause
|
83
user.go
83
user.go
|
@ -1,4 +1,5 @@
|
|||
package main
|
||||
import "fmt"
|
||||
import "strings"
|
||||
import "strconv"
|
||||
import "net/http"
|
||||
|
@ -26,6 +27,8 @@ type User struct
|
|||
URLPrefix string
|
||||
URLName string
|
||||
Tag string
|
||||
Level int
|
||||
Score int
|
||||
}
|
||||
|
||||
type Email struct
|
||||
|
@ -92,7 +95,7 @@ func SessionCheck(w http.ResponseWriter, r *http.Request) (user User, noticeList
|
|||
user.Session = cookie.Value
|
||||
|
||||
// Is this session valid..?
|
||||
err = get_session_stmt.QueryRow(user.ID,user.Session).Scan(&user.ID, &user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName)
|
||||
err = get_session_stmt.QueryRow(user.ID,user.Session).Scan(&user.ID, &user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score)
|
||||
if err == sql.ErrNoRows {
|
||||
user.ID = 0
|
||||
user.Session = ""
|
||||
|
@ -154,7 +157,7 @@ func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (user User, succ
|
|||
user.Session = cookie.Value
|
||||
|
||||
// Is this session valid..?
|
||||
err = get_session_stmt.QueryRow(user.ID,user.Session).Scan(&user.ID, &user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName)
|
||||
err = get_session_stmt.QueryRow(user.ID,user.Session).Scan(&user.ID, &user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score)
|
||||
if err == sql.ErrNoRows {
|
||||
user.ID = 0
|
||||
user.Session = ""
|
||||
|
@ -189,3 +192,79 @@ func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (user User, succ
|
|||
}
|
||||
return user, true
|
||||
}
|
||||
|
||||
func increase_post_user_stats(wcount int, uid int, topic bool, user User) error {
|
||||
var mod int
|
||||
base_score := 1
|
||||
if topic {
|
||||
_, err := increment_user_topics_stmt.Exec(1, uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
base_score = 2
|
||||
}
|
||||
|
||||
if wcount > settings["megapost_min_chars"].(int) {
|
||||
_, err := increment_user_megaposts_stmt.Exec(1,1,1,uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mod = 4
|
||||
} else if wcount > settings["bigpost_min_chars"].(int) {
|
||||
_, err := increment_user_bigposts_stmt.Exec(1,1,uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mod = 1
|
||||
} else {
|
||||
_, err := increment_user_posts_stmt.Exec(1,uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
_, err := increment_user_score_stmt.Exec(base_score + mod, uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(user.Score + base_score + mod)
|
||||
fmt.Println(getLevel(user.Score + base_score + mod))
|
||||
_, err = update_user_level_stmt.Exec(getLevel(user.Score + base_score + mod), uid)
|
||||
return err
|
||||
}
|
||||
|
||||
func decrease_post_user_stats(wcount int, uid int, topic bool, user User) error {
|
||||
var mod int
|
||||
base_score := -1
|
||||
if topic {
|
||||
_, err := increment_user_topics_stmt.Exec(-1, uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
base_score = -2
|
||||
}
|
||||
|
||||
if wcount > settings["megapost_min_chars"].(int) {
|
||||
_, err := increment_user_megaposts_stmt.Exec(-1,-1,-1,uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mod = 4
|
||||
} else if wcount > settings["bigpost_min_chars"].(int) {
|
||||
_, err := increment_user_bigposts_stmt.Exec(-1,-1,uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mod = 1
|
||||
} else {
|
||||
_, err := increment_user_posts_stmt.Exec(-1,uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
_, err := increment_user_score_stmt.Exec(base_score - mod, uid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = update_user_level_stmt.Exec(getLevel(user.Score - base_score - mod), uid)
|
||||
return err
|
||||
}
|
||||
|
|
84
utils.go
84
utils.go
|
@ -3,6 +3,9 @@ import "log"
|
|||
import "fmt"
|
||||
import "time"
|
||||
import "os"
|
||||
import "math"
|
||||
import "strings"
|
||||
import "unicode"
|
||||
import "encoding/base64"
|
||||
import "crypto/rand"
|
||||
import "net/smtp"
|
||||
|
@ -103,3 +106,84 @@ func write_file(name string, content string) {
|
|||
f.Sync()
|
||||
f.Close()
|
||||
}
|
||||
|
||||
func word_count(input string) int {
|
||||
input = strings.TrimSpace(input)
|
||||
count := 0
|
||||
in_space := false
|
||||
for _, value := range input {
|
||||
if unicode.IsSpace(value) {
|
||||
if !in_space {
|
||||
in_space = true
|
||||
}
|
||||
} else if in_space {
|
||||
count++
|
||||
in_space = false
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
func getLevel(score int) (level int) {
|
||||
var base float64 = 25
|
||||
var current float64
|
||||
var prev float64
|
||||
exp_factor := 2.8
|
||||
|
||||
for i := 1;;i++ {
|
||||
_, bit := math.Modf(float64(i) / 10)
|
||||
if bit == 0 {
|
||||
exp_factor += 0.1
|
||||
}
|
||||
current = base + math.Pow(float64(i), exp_factor) + (prev / 3)
|
||||
prev = current
|
||||
if float64(score) < current {
|
||||
break
|
||||
} else {
|
||||
level++
|
||||
}
|
||||
}
|
||||
return level
|
||||
}
|
||||
|
||||
func getLevelScore(getLevel int) (score int) {
|
||||
var base float64 = 25
|
||||
var current float64
|
||||
var prev float64
|
||||
var level int
|
||||
exp_factor := 2.8
|
||||
|
||||
for i := 1;;i++ {
|
||||
_, bit := math.Modf(float64(i) / 10)
|
||||
if bit == 0 {
|
||||
exp_factor += 0.1
|
||||
}
|
||||
current = base + math.Pow(float64(i), exp_factor) + (prev / 3)
|
||||
prev = current
|
||||
level++
|
||||
if level <= getLevel {
|
||||
break
|
||||
}
|
||||
}
|
||||
return int(math.Ceil(current))
|
||||
}
|
||||
|
||||
func getLevels(maxLevel int) []float64 {
|
||||
var base float64 = 25
|
||||
var current float64 = 0
|
||||
var prev float64 = 0
|
||||
exp_factor := 2.8
|
||||
var out []float64
|
||||
out = append(out, 0)
|
||||
|
||||
for i := 1;i <= maxLevel;i++ {
|
||||
_, bit := math.Modf(float64(i) / 10)
|
||||
if bit == 0 {
|
||||
exp_factor += 0.1
|
||||
}
|
||||
current = base + math.Pow(float64(i), exp_factor) + (prev / 3)
|
||||
prev = current
|
||||
out = append(out, current)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue