Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Game/MainScene.gd
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,13 @@ func _on_Player_holePinafullyStretched(bodypart, _who):
addMessage("OW! Your pussy [b]hurts[/b]..")
if(bodypart == BodypartSlot.Anus):
addMessage("OW! Your anus [b]hurts[/b]..")
callPainWebhook(bodypart)

func callPainWebhook(bodypart):
var jsonStr = ""
if(OPTIONS.getWebhookPainEnabled()):
jsonStr= '{"action": "painstretch","bodypart": "' + str(bodypart) + '"}'
$HTTPRequest.request(OPTIONS.getWebhookURL(), ["Content-Type: application/json"], true, HTTPClient.METHOD_POST , jsonStr)

func _on_Player_gotWoundedBy(_who):
addMessage("OW! That [b]really[/b] hurt..")
Expand Down
2 changes: 2 additions & 0 deletions Game/MainScene.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ script = ExtResource( 2 )

[node name="DynamicCharacters" type="Node" parent="."]

[node name="HTTPRequest" type="HTTPRequest" parent="."]

[connection signal="onDevComButton" from="GameUI" to="." method="_on_GameUI_onDevComButton"]
[connection signal="on_option_button" from="GameUI" to="." method="_on_GameUI_on_option_button"]
[connection signal="on_rollback_button" from="GameUI" to="." method="_on_GameUI_on_rollback_button"]
52 changes: 52 additions & 0 deletions Game/Options/GlobalOptions.gd
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ var visibleWritings:bool = true
var autosaveEnabled = true

var genderNamesOverrides = {}
var webhookURL = "https://webhook.xtoys.app/abcrandomidentifier"
var webhookStatsEnabled = false
var webhookPainEnabled = false

func resetToDefaults():
fetchNewRelease = true
Expand Down Expand Up @@ -312,6 +315,14 @@ func getInventoryIconSize():
if(inventoryIconsSize == "big"):
return 64
return 32
func getWebhookStatsEnabled():
return webhookStatsEnabled

func getWebhookPainEnabled():
return webhookPainEnabled

func getWebhookURL():
return webhookURL

func getChangeableOptions():
var settings = [
Expand Down Expand Up @@ -879,6 +890,33 @@ func getChangeableOptions():
},
]
},
{
"name": "Webhook",
"id": "webhook",
"options": [
{
"name": "Webhook base URL",
"description": "The base URL of the webhook",
"id": "webhookURL",
"type": "string",
"value": webhookURL,
},
{
"name": "Stats enabled",
"description": "Sends POST requests with basic player character stats",
"id": "webhookStatsEnabled",
"type": "checkbox",
"value": webhookStatsEnabled,
},
{
"name": "Painful insertions enabled",
"description": "Sends POST requests with painful insertion information",
"id": "webhookPainEnabled",
"type": "checkbox",
"value": webhookPainEnabled,
},
]
},
{
"name": "Debug",
"id": "debug",
Expand Down Expand Up @@ -1068,6 +1106,14 @@ func applyOption(categoryID, optionID, value):
if(optionID == "visibleWritings"):
visibleWritings = value

if(categoryID == "webhook"):
if(optionID == "webhookStatsEnabled"):
webhookStatsEnabled = value
if(optionID == "webhookPainEnabled"):
webhookPainEnabled = value
if(optionID == "webhookURL"):
webhookURL = value

if(categoryID == "debug"):
if(optionID == "debugPanel"):
debugPanel = value
Expand Down Expand Up @@ -1160,6 +1206,9 @@ func saveData():
"blockCatcherPanelHeight": blockCatcherPanelHeight,
"webTextInputFallback": webTextInputFallback,
"fullscreen": fullscreen,
"webhookStatsEnabled": webhookStatsEnabled,
"webhookPainEnabled": webhookStatsEnabled,
"webhookURL": webhookURL,
}

return data
Expand Down Expand Up @@ -1220,6 +1269,9 @@ func loadData(data):
blockCatcherPanelHeight = loadVar(data, "blockCatcherPanelHeight", 16)
webTextInputFallback = loadVar(data, "webTextInputFallback", false)
fullscreen = loadVar(data, "fullscreen", false)
webhookStatsEnabled = loadVar(data, "webhookStatsEnabled", false)
webhookPainEnabled = loadVar(data, "webhookPainEnabled", false)
webhookURL = loadVar(data, "webhookURL", "https://webhook.xtoys.app/abcrandomid")

func saveToFile():
var saveData = saveData()
Expand Down
13 changes: 13 additions & 0 deletions Game/PlayerPanel.gd
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@ func loadingSavefileFinished():

func on_player_statchange():
updateUI()
callStatsWebhook()

func callStatsWebhook():
var jsonStr = ""
if(OPTIONS.getWebhookStatsEnabled()):
#$HTTPRequest.request(OPTIONS.getWebhookURL)
jsonStr= '{"action": "stats","p": ' + str(GM.pc.getPain()) + ',"pt": ' + str(GM.pc.painThreshold())
jsonStr= jsonStr + ',"l": ' + str(GM.pc.getLust()) + ' ,"lt": ' + str(GM.pc.lustThreshold())
jsonStr= jsonStr + ',"s": ' + str(GM.pc.getStamina()) + ' ,"ms": ' + str(GM.pc.getMaxStamina())
jsonStr= jsonStr + ',"lp": ' + str(int(GM.pc.getSkillsHolder().getLevelProgress()*100)) + ' ,"lvl": ' + str(GM.pc.getSkillsHolder().getLevel())
jsonStr= jsonStr + ',"ar": ' + str(int(GM.pc.getArousal()*100)) + ' ,"ll": ' + str(int(GM.pc.getLustLevel()*100)) + '}'
$HTTPRequest.request(OPTIONS.getWebhookURL(), ["Content-Type: application/json"], true, HTTPClient.METHOD_POST , jsonStr)


func updateUI():
nameLabel.text = GM.pc.getName() + ", " + GM.pc.getSpeciesFullName()
Expand Down
2 changes: 2 additions & 0 deletions Game/PlayerPanel.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ margin_top = -128.289
margin_right = 280.291
margin_bottom = -96.289

[node name="HTTPRequest" type="HTTPRequest" parent="."]

[connection signal="gui_input" from="ViewportWrapper" to="." method="_on_ViewportWrapper_gui_input"]
[connection signal="mouse_entered" from="ViewportWrapper/CustomViewportControl" to="." method="_on_ViewportContainer_mouse_entered"]
[connection signal="mouse_exited" from="ViewportWrapper/CustomViewportControl" to="." method="_on_ViewportContainer_mouse_exited"]
14 changes: 14 additions & 0 deletions Misc/Webhook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Webhook
The webhook settings added in the Options can send the basic statistics to xtoys.app (or any other platform accepting JSON POST) for sex toy automation.

## Usage

1. Open https://xtoys.app and connect to your toys.
2. Add the "BDCC Simple Webhook" script from Public Scripts (or import the Json in webhook_script.txt in the Misc folder)
3. Generate a random id by clicking the dice (might require an xtoys.app account), and copy the random value
4. Open BDCC, go to Options in the Webhook section set the URL to "https://webhook.xtoys.app/RANDOMVALUEHERE" remember to replace RANDOMVALUEHERE with the value from the previous step.
5. Tick the boxes to send either the stats (Pain, Lust, Stamina etc.) or the painful insertion triggers, or both.
6. Connect the script to devices in xtoys.app by clicking the D in the header.
7. Press play on the script in the xtoys.app dashboard.

Stat changes might have an update delay until the in-game scene progresses.
152 changes: 152 additions & 0 deletions Misc/xtoys_script.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
{
"initialActions": [
{
"job": "Main",
"type": "updateJob",
"action": "start"
}
],
"finalActions": [],
"globalTriggers": [
{
"type": "componentState",
"action": "stats",
"actions": [
{
"type": "updateComponent",
"action": "setVolume",
"channel": "generic-1-a",
"rampTime": "1",
"percentVolume": "{trigger-p}*100/{trigger-pt}",
"parsedRampTime": 1
},
{
"type": "updateComponent",
"action": "setVolume",
"channel": "generic-1-b",
"rampTime": "1",
"percentVolume": "{trigger-l} * 100 / {trigger-lt}"
},
{
"type": "updateComponent",
"action": "setVolume",
"channel": "generic-1-c",
"rampTime": "1",
"percentVolume": "{trigger-s} * 100 / {trigger-sm}"
}
],
"channel": "webhook-a",
"parsedAction": "stats"
},
{
"type": "componentState",
"action": "painstretch",
"actions": [
{
"type": "updateComponent",
"action": "setVolume",
"channel": "part-grip-expander-a",
"rampTime": "5",
"percentVolume": "100"
},
{
"type": "updateComponent",
"action": "setVolume",
"channel": "part-grip-expander-a",
"rampTime": "1",
"percentVolume": "0"
}
],
"channel": "webhook-a",
"parsedAction": "painstretch",
"requiredExpression": "{trigger-bodypart} == \"vagina\""
},
{
"type": "componentState",
"action": "painstretch",
"actions": [
{
"type": "updateComponent",
"action": "setVolume",
"channel": "generic-1-a",
"rampTime": "5",
"percentVolume": "100"
},
{
"type": "updateComponent",
"action": "setVolume",
"channel": "generic-1-a",
"rampTime": "1",
"percentVolume": "0"
}
],
"channel": "webhook-a",
"parsedAction": "painstretch",
"requiredExpression": "{trigger-bodypart}==\"anus\""
}
],
"jobs": {
"Main": {
"steps": {
"START": {
"actions": [],
"triggers": []
}
}
},
"Reset Inf": {
"steps": {
"Reset": {
"actions": [],
"triggers": []
},
"START": {
"actions": [],
"triggers": []
}
}
}
},
"queues": [],
"channels": {
"webhook-a": {
"name": "WH",
"type": "webhook",
"outbound": false,
"hideWebhookInfo": false
},
"generic-1-a": {
"name": "Pain %",
"type": "generic-1"
},
"generic-1-b": {
"name": "Lust %",
"type": "generic-1"
},
"generic-1-c": {
"name": "Stamina %",
"type": "generic-1"
},
"part-grip-expander-a": {
"name": "Inflate Vagina",
"type": "part-grip-expander"
},
"part-grip-expander-b": {
"name": "Inflate Anus",
"type": "part-grip-expander"
}
},
"controls": [
{
"id": "p",
"type": "textarea"
}
],
"controlPresets": [],
"media": {
"patterns": {},
"audio": {},
"voices": {}
},
"customFunctions": ""
}