init
This commit is contained in:
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
18
.idea/dataSources.local.xml
generated
18
.idea/dataSources.local.xml
generated
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="dataSourceStorageLocal" created-in="RR-252.23892.452">
|
||||
<data-source name="db.sqlite" uuid="26059583-0fdb-4f6f-ad11-10388e9658c2">
|
||||
<database-info product="SQLite" version="3.45.1" jdbc-version="4.2" driver-name="SQLite JDBC" driver-version="3.45.1.0" dbms="SQLITE" exact-version="3.45.1" exact-driver-version="3.45">
|
||||
<identifier-quote-string>"</identifier-quote-string>
|
||||
</database-info>
|
||||
<case-sensitivity plain-identifiers="mixed" quoted-identifiers="mixed" />
|
||||
<secret-storage>master_key</secret-storage>
|
||||
<auth-provider>no-auth</auth-provider>
|
||||
<schema-mapping>
|
||||
<introspection-scope>
|
||||
<node kind="schema" qname="@" />
|
||||
</introspection-scope>
|
||||
</schema-mapping>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
||||
12
.idea/dataSources.xml
generated
12
.idea/dataSources.xml
generated
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||
<data-source source="LOCAL" name="db.sqlite" uuid="26059583-0fdb-4f6f-ad11-10388e9658c2">
|
||||
<driver-ref>sqlite.xerial</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
|
||||
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/db.sqlite</jdbc-url>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
||||
1923
.idea/dataSources/26059583-0fdb-4f6f-ad11-10388e9658c2.xml
generated
1923
.idea/dataSources/26059583-0fdb-4f6f-ad11-10388e9658c2.xml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
||||
#n:main
|
||||
!<md> [0, 0, null, null, -2147483648, -2147483648]
|
||||
230
.idea/workspace.xml
generated
230
.idea/workspace.xml
generated
@@ -1,9 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AnalysisUIOptions">
|
||||
<option name="ANALYZE_INJECTED_CODE" value="false" />
|
||||
<option name="SCOPE_TYPE" value="3" />
|
||||
</component>
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="ALL" />
|
||||
</component>
|
||||
@@ -15,20 +11,56 @@
|
||||
</cargoProject>
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="ca698286-778f-4335-97c8-da35a666c986" name="Changes" comment="init">
|
||||
<change afterPath="$PROJECT_DIR$/src/store/session/client.rs" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/store/session/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/dataSources.local.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/dataSources.local.xml" afterDir="false" />
|
||||
<list default="true" id="b2b598c9-ef0b-4cbc-8852-cfbc8ce3920e" name="Changes" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/dataSources.local.xml" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/dataSources.xml" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/dataSources/26059583-0fdb-4f6f-ad11-10388e9658c2.xml" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/dataSources/26059583-0fdb-4f6f-ad11-10388e9658c2/storage_v2/_src_/schema/main.uQUzAA.meta" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/modules.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/modules.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/ox_speak_server.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/ox_speak_server.iml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/vcs.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Cargo.lock" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.lock" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Cargo.toml" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.toml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/app/app.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/app.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/app/conf.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/conf.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/app/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/domain/client.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/domain/client.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/domain/event.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/domain/event.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/domain/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/domain/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/domain/models.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/domain/models.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/domain/user.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/domain/user.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/lib.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/lib.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/network/http.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/network/http.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/network/http_routes/channel.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/network/http_routes/channel.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/network/http_routes/master.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/network/http_routes/master.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/network/http_routes/message.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/network/http_routes/message.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/network/http_routes/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/network/http_routes/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/network/http_routes/sub_server.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/network/http_routes/sub_server.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/network/http_routes/user.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/network/http_routes/user.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/network/http_routes/websocket.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/network/http_routes/websocket.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/network/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/network/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/network/protocol.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/network/protocol.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/network/udp.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/network/udp.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/network/udp_back.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/network/udp_back.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/runtime/dispatcher.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/runtime/dispatcher.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/store/migrations/001_init.sqlite.sql" beforeDir="false" afterPath="$PROJECT_DIR$/src/store/migrations/001_init.sqlite.sql" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/store/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/store/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/store/models/channel.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/store/models/channel.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/store/models/link_sub_server_user.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/store/models/link_sub_server_user.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/store/models/message.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/store/models/message.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/store/models/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/store/models/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/store/models/sub_server.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/store/models/sub_server.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/store/models/user.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/store/models/user.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/store/repositories/channel_repository.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/store/repositories/channel_repository.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/store/repositories/link_sub_server_user_repository.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/store/repositories/link_sub_server_user_repository.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/store/repositories/message_repository.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/store/repositories/message_repository.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/store/repositories/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/store/repositories/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/store/repositories/sub_server_repository.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/store/repositories/sub_server_repository.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/store/repositories/user_repository.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/store/repositories/user_repository.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/store/session/client.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/store/session/client.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/store/store_service.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/store/store_service.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/utils/shared_store.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/utils/shared_store.rs" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
@@ -37,43 +69,32 @@
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="ExecutionTargetManager" SELECTED_TARGET="RsBuildProfile:dev" />
|
||||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="Rust File" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_BRANCH_BY_REPOSITORY">
|
||||
<map>
|
||||
<entry key="$PROJECT_DIR$" value="be761a8c4601d565574e6d42ad4711e6c054fc75" />
|
||||
</map>
|
||||
</option>
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="MacroExpansionManager">
|
||||
<option name="directoryName" value="oBePpDlK" />
|
||||
<option name="directoryName" value="j91G0RKo" />
|
||||
</component>
|
||||
<component name="ProjectColorInfo">{
|
||||
"associatedIndex": 5
|
||||
"associatedIndex": 7
|
||||
}</component>
|
||||
<component name="ProjectId" id="2zaZ93S6zEp6mJe7Xq5WfvIMexv" />
|
||||
<component name="ProjectId" id="31h5TOFgo6LtoeKpSInG1hXoNI7" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">{
|
||||
"keyToString": {
|
||||
"Cargo.Run.executor": "Run",
|
||||
"Cargo.Run ox_speak_server.executor": "Run",
|
||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"RunOnceActivity.rust.reset.selective.auto.import": "true",
|
||||
"git-widget-placeholder": "master",
|
||||
"ignore.virus.scanning.warn.message": "true",
|
||||
"junie.onboarding.icon.badge.shown": "true",
|
||||
"last_opened_file_path": "D:/Dev/ox_speak_server/src/network",
|
||||
"last_opened_file_path": "//wsl.localhost/Debian/home/Nell/linux_dev/ox_speak_server",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
@@ -82,28 +103,14 @@
|
||||
"org.rust.cargo.project.model.PROJECT_DISCOVERY": "true",
|
||||
"org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon": "",
|
||||
"org.rust.first.attach.projects": "true",
|
||||
"run.code.analysis.last.selected.profile": "pProject Default",
|
||||
"settings.editor.selected.configurable": "junie.allowlist",
|
||||
"settings.editor.selected.configurable": "preferences.pluginManager",
|
||||
"to.speed.mode.migration.done": "true",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
},
|
||||
"keyToStringList": {
|
||||
"DatabaseDriversLRU": [
|
||||
"sqlite"
|
||||
]
|
||||
}
|
||||
}</component>
|
||||
<component name="RecentsManager">
|
||||
<key name="CopyFile.RECENT_KEYS">
|
||||
<recent name="D:\Dev\ox_speak_server\src\network" />
|
||||
</key>
|
||||
<key name="MoveFile.RECENT_KEYS">
|
||||
<recent name="D:\Dev\ox_speak_server\src\store" />
|
||||
<recent name="D:\Dev\ox_speak_server\src\store\repositories" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="RunManager">
|
||||
<configuration name="Run" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
|
||||
<component name="RunManager" selected="Cargo.Run ox_speak_server">
|
||||
<configuration name="Run ox_speak_server" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
|
||||
<option name="buildProfileId" value="dev" />
|
||||
<option name="command" value="run --package ox_speak_server --bin ox_speak_server" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
||||
<envs />
|
||||
@@ -120,133 +127,42 @@
|
||||
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration name="Test ox_speak_server" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
|
||||
<option name="command" value="test --workspace" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
||||
<envs />
|
||||
<option name="emulateTerminal" value="true" />
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="requiredFeatures" value="true" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="withSudo" value="false" />
|
||||
<option name="buildTarget" value="REMOTE" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<option name="isRedirectInput" value="false" />
|
||||
<option name="redirectInputPath" value="" />
|
||||
<method v="2">
|
||||
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
<component name="RustProjectSettings">
|
||||
<option name="toolchainHomeDirectory" value="$USER_HOME$/.cargo/bin" />
|
||||
<option name="toolchainHomeDirectory" value="$PROJECT_DIR$/../../.cargo/bin" />
|
||||
</component>
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="ca698286-778f-4335-97c8-da35a666c986" name="Changes" comment="" />
|
||||
<created>1751970990022</created>
|
||||
<changelist id="b2b598c9-ef0b-4cbc-8852-cfbc8ce3920e" name="Changes" comment="" />
|
||||
<created>1755963473950</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1751970990022</updated>
|
||||
<workItem from="1751970991653" duration="7327000" />
|
||||
<workItem from="1752016714585" duration="1095000" />
|
||||
<workItem from="1752076174877" duration="11015000" />
|
||||
<workItem from="1752189013977" duration="4750000" />
|
||||
<workItem from="1752224469499" duration="14591000" />
|
||||
<workItem from="1752305152715" duration="19879000" />
|
||||
<workItem from="1752391851097" duration="12061000" />
|
||||
<workItem from="1752446764168" duration="8166000" />
|
||||
<workItem from="1752484190578" duration="17709000" />
|
||||
<workItem from="1752591656862" duration="429000" />
|
||||
<workItem from="1752593250094" duration="11969000" />
|
||||
<workItem from="1752694022400" duration="6212000" />
|
||||
<workItem from="1752741840195" duration="2946000" />
|
||||
<workItem from="1752833798325" duration="5366000" />
|
||||
<workItem from="1752917416027" duration="1192000" />
|
||||
<workItem from="1752931843330" duration="2938000" />
|
||||
<workItem from="1752997629708" duration="9070000" />
|
||||
<workItem from="1753107912894" duration="595000" />
|
||||
<workItem from="1753225761416" duration="1356000" />
|
||||
<workItem from="1753282037526" duration="5207000" />
|
||||
<workItem from="1753397680991" duration="1782000" />
|
||||
<workItem from="1753399490773" duration="3189000" />
|
||||
<workItem from="1753436756029" duration="16895000" />
|
||||
<workItem from="1753521176318" duration="17811000" />
|
||||
<workItem from="1753601912332" duration="5843000" />
|
||||
<workItem from="1753718175508" duration="8774000" />
|
||||
<workItem from="1753800817354" duration="3570000" />
|
||||
<workItem from="1753804571241" duration="59000" />
|
||||
<workItem from="1753804642657" duration="236000" />
|
||||
<workItem from="1753804898179" duration="625000" />
|
||||
<workItem from="1753805533139" duration="2956000" />
|
||||
<workItem from="1753868593668" duration="550000" />
|
||||
<workItem from="1753869165302" duration="389000" />
|
||||
<workItem from="1753869606067" duration="448000" />
|
||||
<workItem from="1753870068458" duration="3339000" />
|
||||
<workItem from="1753975758350" duration="2576000" />
|
||||
<workItem from="1754003476744" duration="2622000" />
|
||||
<workItem from="1754006134163" duration="1746000" />
|
||||
<workItem from="1754007911864" duration="414000" />
|
||||
<workItem from="1754039613630" duration="3435000" />
|
||||
<workItem from="1754131509073" duration="779000" />
|
||||
<workItem from="1754132326149" duration="52000" />
|
||||
<workItem from="1754132390785" duration="5048000" />
|
||||
<workItem from="1754211612647" duration="13365000" />
|
||||
<workItem from="1754321796199" duration="4611000" />
|
||||
<workItem from="1754409493435" duration="2864000" />
|
||||
<workItem from="1754521183720" duration="4070000" />
|
||||
<workItem from="1754761637246" duration="1293000" />
|
||||
<workItem from="1754781483976" duration="3949000" />
|
||||
<workItem from="1754923017894" duration="1334000" />
|
||||
<updated>1755963473950</updated>
|
||||
<workItem from="1755963475439" duration="2760000" />
|
||||
<workItem from="1756139974994" duration="110000" />
|
||||
</task>
|
||||
<task id="LOCAL-00001" summary="init">
|
||||
<option name="closed" value="true" />
|
||||
<created>1752591904243</created>
|
||||
<option name="number" value="00001" />
|
||||
<option name="presentableId" value="LOCAL-00001" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1752591904243</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00002" summary="init">
|
||||
<option name="closed" value="true" />
|
||||
<created>1752591989113</created>
|
||||
<option name="number" value="00002" />
|
||||
<option name="presentableId" value="LOCAL-00002" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1752591989113</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00003" summary="init">
|
||||
<option name="closed" value="true" />
|
||||
<created>1753813204617</created>
|
||||
<option name="number" value="00003" />
|
||||
<option name="presentableId" value="LOCAL-00003" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1753813204617</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00004" summary="init">
|
||||
<option name="closed" value="true" />
|
||||
<created>1754213783870</created>
|
||||
<option name="number" value="00004" />
|
||||
<option name="presentableId" value="LOCAL-00004" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1754213783870</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="5" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
<component name="Vcs.Log.Tabs.Properties">
|
||||
<option name="TAB_STATES">
|
||||
<map>
|
||||
<entry key="MAIN">
|
||||
<value>
|
||||
<State>
|
||||
<option name="FILTERS">
|
||||
<map>
|
||||
<entry key="branch">
|
||||
<value>
|
||||
<list>
|
||||
<option value="master" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</State>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
<component name="VcsManagerConfiguration">
|
||||
<MESSAGE value="init" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="init" />
|
||||
</component>
|
||||
<component name="XSLT-Support.FileAssociations.UIState">
|
||||
<expand />
|
||||
<select />
|
||||
|
||||
16
Cargo.lock
generated
16
Cargo.lock
generated
@@ -1432,12 +1432,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.5.10"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
|
||||
checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1776,9 +1776,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.46.1"
|
||||
version = "1.47.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17"
|
||||
checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
@@ -1791,7 +1791,7 @@ dependencies = [
|
||||
"slab",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1969,9 +1969,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.17.0"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d"
|
||||
checksum = "f33196643e165781c20a5ead5582283a7dacbb87855d867fbc2df3f81eddc1be"
|
||||
dependencies = [
|
||||
"getrandom 0.3.3",
|
||||
"js-sys",
|
||||
|
||||
@@ -17,9 +17,9 @@ debug = true
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
parking_lot = "0.12"
|
||||
tokio = { version = "1.46", features = ["full"] }
|
||||
tokio = { version = "1.47", features = ["full"] }
|
||||
strum = {version = "0.27", features = ["derive"] }
|
||||
uuid = {version = "1.17", features = ["v4", "serde"] }
|
||||
uuid = {version = "1.18", features = ["v4", "serde"] }
|
||||
event-listener = "5.4"
|
||||
dashmap = "6.1"
|
||||
bytes = "1.10"
|
||||
|
||||
@@ -3,3 +3,4 @@ créer un fichier de migration sqlx :
|
||||
sqlx migrate add --source src/store/migrations migration_name
|
||||
```
|
||||
|
||||
# Example
|
||||
@@ -1,11 +1,9 @@
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::Arc;
|
||||
use axum::{
|
||||
extract::{ws::WebSocket, ws::WebSocketUpgrade, State},
|
||||
response::Response,
|
||||
Json, Router,
|
||||
routing::{get, post}
|
||||
};
|
||||
use axum::{extract::{ws::WebSocket, ws::WebSocketUpgrade, State}, response::Response, Json, Router, routing::{get, post}, middleware};
|
||||
use axum::body::Body;
|
||||
use axum::http::{HeaderValue, Request, StatusCode};
|
||||
use axum::middleware::Next;
|
||||
use tokio::net::TcpListener;
|
||||
use crate::domain::event::EventBus;
|
||||
use crate::network::http_routes::master;
|
||||
@@ -46,7 +44,8 @@ impl HttpServer {
|
||||
|
||||
fn create_router(&self) -> Router {
|
||||
let api_route = Router::new()
|
||||
.nest("/master", master::create_router());
|
||||
.nest("/master", master::create_router())
|
||||
.layer(middleware::from_fn(app_only_middleware));
|
||||
|
||||
Router::new()
|
||||
.nest("/api", api_route)
|
||||
@@ -68,3 +67,23 @@ impl HttpServer {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Middlewares
|
||||
async fn app_only_middleware(request: Request<Body>, next: Next) -> Result<Response, StatusCode> {
|
||||
let headers = request.headers();
|
||||
let expected_client = HeaderValue::from_static("ox_speak");
|
||||
let expected_version = HeaderValue::from_static("1.0");
|
||||
let expected_user_agent = HeaderValue::from_static("OxSpeak/1.0");
|
||||
|
||||
if headers.get("X-Client-Type") != Some(&expected_client) ||
|
||||
headers.get("X-Protocol-Version") != Some(&expected_version) ||
|
||||
headers.get("User-Agent") != Some(&expected_user_agent) {
|
||||
return Ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body("Invalid client".into())
|
||||
.unwrap());
|
||||
}
|
||||
|
||||
Ok(next.run(request).await)
|
||||
|
||||
}
|
||||
@@ -10,9 +10,37 @@ use crate::network::http::HttpState;
|
||||
|
||||
pub fn create_router() -> Router<HttpState> {
|
||||
Router::new()
|
||||
.route("/auth/", post(join_master_server))
|
||||
.route("/auth/", post(join))
|
||||
}
|
||||
|
||||
pub async fn join_master_server(State(state): State<HttpState>) -> Json<HashMap<String, String>> {
|
||||
todo!("join master server")
|
||||
pub async fn challenge(State(state): State<HttpState>) -> Json<HashMap<String, String>> {
|
||||
// permet de sécuriser les échanges entre le client et le serveur pour qu'elle soit propre à l'application
|
||||
// l'idée est d'éviter que les système comme les navigateurs, curl ... puisse accéder à l'application
|
||||
todo!("challenge master server")
|
||||
}
|
||||
|
||||
pub async fn join(State(state): State<HttpState>) -> Json<HashMap<String, String>> {
|
||||
// Cette page est systématiquement appelé à la première connexion du client
|
||||
// dans le payload de la requête, on aura les info client
|
||||
// public key
|
||||
// dans la réponse, on aura le status
|
||||
// success, error, password_needed
|
||||
|
||||
// match determine_server_state().await {
|
||||
// ServerState::FirstSetup => {
|
||||
// // Logique de création du super admin
|
||||
// // Validation des champs requis (password, username)
|
||||
// }
|
||||
// ServerState::RequiresPassword => {
|
||||
// // Logique d'authentification
|
||||
// // Validation du mot de passe serveur
|
||||
// }
|
||||
// ServerState::Ready => {
|
||||
// // Logique de connexion normale
|
||||
// // Juste la public key suffit
|
||||
// }
|
||||
// }
|
||||
|
||||
todo!("join master server")
|
||||
|
||||
}
|
||||
@@ -3,7 +3,6 @@ pub mod channel;
|
||||
pub mod user;
|
||||
pub mod message;
|
||||
pub mod link_sub_server_user;
|
||||
mod models;
|
||||
|
||||
pub use sub_server::*;
|
||||
pub use channel::*;
|
||||
|
||||
@@ -103,7 +103,7 @@ pub struct ClientManager {
|
||||
/// Index des clients par channel_id
|
||||
voice_channel_clients: SharedArcMap<Channel, SharedArcHashSet<Client>>, // channel_id -> HashSet<session_id>
|
||||
/// Index des clients par sub_server_id
|
||||
sub_server_clients: SharedArcMap<Uuid, SharedArcVec<Client>>, // sub_server_id -> Vec<session_id>
|
||||
sub_server_clients: SharedArcMap<SubServer, SharedArcHashSet<Client>>, // sub_server_id -> Vec<session_id>
|
||||
/// Index des clients par adresse UDP
|
||||
udp_clients: SharedArcMap<SocketAddr, String>, // udp_address -> session_id
|
||||
}
|
||||
@@ -135,9 +135,18 @@ impl ClientManager {
|
||||
arc_client
|
||||
}
|
||||
|
||||
pub fn join_sub_server(&self, client: &Arc<Client>, sub_server: &SubServer) {
|
||||
let clients = self.sub_server_clients.get(sub_server).unwrap_or_else(|| {
|
||||
let new_clients = Arc::new(SharedArcHashSet::new());
|
||||
self.sub_server_clients.insert_arc(sub_server.clone(), new_clients.clone());
|
||||
new_clients
|
||||
});
|
||||
|
||||
clients.insert_arc(client.clone());
|
||||
}
|
||||
|
||||
/// Obtient un client par son session_id
|
||||
pub fn get_client(&self, session_id: &Uuid) -> Option<Arc<Client>> {
|
||||
// Convertir &str en String pour les clés
|
||||
self.clients.get(session_id)
|
||||
}
|
||||
|
||||
@@ -159,35 +168,14 @@ impl ClientManager {
|
||||
///
|
||||
/// # Returns
|
||||
/// `true` si le client a été trouvé et modifié, `false` sinon
|
||||
pub fn modify_client<F>(&self, session_id: &str, f: F) -> bool
|
||||
pub fn modify_client<F>(&self, client: &Client, f: F) -> bool
|
||||
where
|
||||
F: FnOnce(&mut Client),
|
||||
{
|
||||
// Convertir &str en String pour les clés
|
||||
self.clients.modify(&session_id.to_string(), f)
|
||||
|
||||
todo!()
|
||||
}
|
||||
|
||||
// ===== OPÉRATIONS ATOMIQUES HAUT NIVEAU =====
|
||||
|
||||
// Nettoie tous les index d'un client (appelé lors de la suppression)
|
||||
// pub(crate) fn cleanup_client_indexes(&self, session_id: &str) {
|
||||
// if let Some(client) = self.get_client(session_id) {
|
||||
// // Nettoyer l'index des channels
|
||||
// if let Some(channel_id) = client.current_channel {
|
||||
// self.remove_from_channel_index(session_id, channel_id);
|
||||
// }
|
||||
//
|
||||
// // Nettoyer l'index des sub-servers
|
||||
// if let Some(sub_server_id) = client.current_sub_server {
|
||||
// self.remove_from_sub_server_index(session_id, sub_server_id);
|
||||
// }
|
||||
//
|
||||
// // Nettoyer l'index UDP
|
||||
// if let Some(udp_address) = client.udp_socket {
|
||||
// self.udp_clients.remove(&udp_address);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
impl ClientManager {
|
||||
@@ -219,16 +207,7 @@ impl ClientManager {
|
||||
|
||||
pub fn remove_client_from_sub_servers(&self, client: &Client) {
|
||||
for (sub_server, clients) in self.sub_server_clients.iter() {
|
||||
let mut to_remove = Vec::<usize>::new();
|
||||
for (index, client) in clients.iter().enumerate() {
|
||||
if client == client {
|
||||
to_remove.push(index);
|
||||
}
|
||||
}
|
||||
|
||||
for idx in to_remove.iter() {
|
||||
clients.
|
||||
}
|
||||
clients.remove(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -246,87 +246,68 @@ impl<T> SharedVec<T> {
|
||||
|
||||
/// Supprime l'élément à l'index donné et le retourne.
|
||||
/// Retourne `None` si l'index est hors limites.
|
||||
///
|
||||
/// Exemple : `let removed = clients.delete(2); // Supprime le 3e client`
|
||||
pub fn delete(&self, index: usize) -> Option<T>
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
loop {
|
||||
let current = self.inner.load();
|
||||
|
||||
if index >= current.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut new_vec = current.as_ref().clone();
|
||||
let removed_item = new_vec.remove(index);
|
||||
|
||||
let new_arc = Arc::new(new_vec);
|
||||
|
||||
if self.inner.compare_and_swap(¤t, new_arc).is_ok() {
|
||||
return Some(removed_item);
|
||||
}
|
||||
// Retry si le CAS a échoué
|
||||
let current = self.inner.load_full();
|
||||
if index >= current.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut new_vec = current.as_ref().clone();
|
||||
let removed_item = new_vec.remove(index);
|
||||
self.inner.store(Arc::new(new_vec));
|
||||
Some(removed_item)
|
||||
}
|
||||
|
||||
/// Supprime et retourne le dernier élément du vecteur.
|
||||
/// Retourne `None` si le vecteur est vide.
|
||||
///
|
||||
/// Exemple : `let last_client = clients.pop(); // Supprime le dernier client`
|
||||
pub fn pop(&self) -> Option<T>
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
loop {
|
||||
let current = self.inner.load();
|
||||
|
||||
if current.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut new_vec = current.as_ref().clone();
|
||||
let popped_item = new_vec.pop();
|
||||
|
||||
let new_arc = Arc::new(new_vec);
|
||||
|
||||
if self.inner.compare_and_swap(¤t, new_arc).is_ok() {
|
||||
return popped_item;
|
||||
}
|
||||
// Retry si le CAS a échoué
|
||||
let current = self.inner.load_full();
|
||||
if current.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut new_vec = current.as_ref().clone();
|
||||
let popped_item = new_vec.pop();
|
||||
self.inner.store(Arc::new(new_vec));
|
||||
popped_item
|
||||
}
|
||||
|
||||
/// Supprime tous les éléments qui correspondent au prédicat donné.
|
||||
/// Retourne le nombre d'éléments supprimés.
|
||||
///
|
||||
/// Exemple : `let removed = clients.delete_matching(|c| c.is_disconnected());`
|
||||
pub fn delete_matching<F>(&self, predicate: F) -> usize
|
||||
where
|
||||
T: Clone,
|
||||
F: Fn(&T) -> bool,
|
||||
{
|
||||
loop {
|
||||
let current = self.inner.load();
|
||||
let mut new_vec = Vec::with_capacity(current.len());
|
||||
let mut removed_count = 0;
|
||||
let current = self.inner.load_full();
|
||||
let mut new_vec = Vec::with_capacity(current.len());
|
||||
let mut removed_count = 0;
|
||||
|
||||
for item in current.iter() {
|
||||
if predicate(item) {
|
||||
removed_count += 1;
|
||||
} else {
|
||||
new_vec.push(item.clone());
|
||||
}
|
||||
for item in current.iter() {
|
||||
if predicate(item) {
|
||||
removed_count += 1;
|
||||
} else {
|
||||
new_vec.push(item.clone());
|
||||
}
|
||||
|
||||
if removed_count == 0 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let new_arc = Arc::new(new_vec);
|
||||
|
||||
if self.inner.compare_and_swap(¤t, new_arc).is_ok() {
|
||||
return removed_count;
|
||||
}
|
||||
// Retry si le CAS a échoué
|
||||
}
|
||||
}
|
||||
|
||||
if removed_count > 0 {
|
||||
self.inner.store(Arc::new(new_vec));
|
||||
}
|
||||
removed_count
|
||||
}
|
||||
|
||||
/// Clear optimisé
|
||||
///
|
||||
@@ -939,45 +920,29 @@ impl<T> SharedArcVec<T> {
|
||||
/// Supprime l'élément à l'index donné et le retourne.
|
||||
/// Retourne `None` si l'index est hors limites.
|
||||
pub fn delete(&self, index: usize) -> Option<Arc<T>> {
|
||||
loop {
|
||||
let current = self.inner.load();
|
||||
|
||||
if index >= current.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut new_vec = current.as_ref().clone();
|
||||
let removed_item = new_vec.remove(index);
|
||||
|
||||
let new_arc = Arc::new(new_vec);
|
||||
|
||||
if self.inner.compare_and_swap(¤t, new_arc).is_ok() {
|
||||
return Some(removed_item);
|
||||
}
|
||||
// Retry si le CAS a échoué
|
||||
let current = self.inner.load_full();
|
||||
if index >= current.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut new_vec = current.as_ref().clone();
|
||||
let removed_item = new_vec.remove(index);
|
||||
self.inner.store(Arc::new(new_vec));
|
||||
Some(removed_item)
|
||||
}
|
||||
|
||||
/// Supprime et retourne le dernier élément du vecteur.
|
||||
/// Retourne `None` si le vecteur est vide.
|
||||
pub fn pop(&self) -> Option<Arc<T>> {
|
||||
loop {
|
||||
let current = self.inner.load();
|
||||
|
||||
if current.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut new_vec = current.as_ref().clone();
|
||||
let popped_item = new_vec.pop();
|
||||
|
||||
let new_arc = Arc::new(new_vec);
|
||||
|
||||
if self.inner.compare_and_swap(¤t, new_arc).is_ok() {
|
||||
return popped_item;
|
||||
}
|
||||
// Retry si le CAS a échoué
|
||||
let current = self.inner.load_full();
|
||||
if current.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut new_vec = current.as_ref().clone();
|
||||
let popped_item = new_vec.pop();
|
||||
self.inner.store(Arc::new(new_vec));
|
||||
popped_item
|
||||
}
|
||||
|
||||
/// Supprime tous les éléments qui correspondent au prédicat donné.
|
||||
@@ -986,30 +951,22 @@ impl<T> SharedArcVec<T> {
|
||||
where
|
||||
F: Fn(&T) -> bool,
|
||||
{
|
||||
loop {
|
||||
let current = self.inner.load();
|
||||
let mut new_vec = Vec::with_capacity(current.len());
|
||||
let mut removed_count = 0;
|
||||
let current = self.inner.load_full();
|
||||
let mut new_vec = Vec::with_capacity(current.len());
|
||||
let mut removed_count = 0;
|
||||
|
||||
for item in current.iter() {
|
||||
if predicate(item.as_ref()) {
|
||||
removed_count += 1;
|
||||
} else {
|
||||
new_vec.push(item.clone());
|
||||
}
|
||||
for item in current.iter() {
|
||||
if predicate(item.as_ref()) {
|
||||
removed_count += 1;
|
||||
} else {
|
||||
new_vec.push(item.clone());
|
||||
}
|
||||
|
||||
if removed_count == 0 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let new_arc = Arc::new(new_vec);
|
||||
|
||||
if self.inner.compare_and_swap(¤t, new_arc).is_ok() {
|
||||
return removed_count;
|
||||
}
|
||||
// Retry si le CAS a échoué
|
||||
}
|
||||
|
||||
if removed_count > 0 {
|
||||
self.inner.store(Arc::new(new_vec));
|
||||
}
|
||||
removed_count
|
||||
}
|
||||
|
||||
/// Supprime le premier élément trouvé qui correspond au prédicat.
|
||||
@@ -1018,30 +975,23 @@ impl<T> SharedArcVec<T> {
|
||||
where
|
||||
F: Fn(&T) -> bool,
|
||||
{
|
||||
loop {
|
||||
let current = self.inner.load();
|
||||
let mut found_index = None;
|
||||
let current = self.inner.load_full();
|
||||
let mut found_index = None;
|
||||
|
||||
for (index, item) in current.iter().enumerate() {
|
||||
if predicate(item.as_ref()) {
|
||||
found_index = Some(index);
|
||||
break;
|
||||
}
|
||||
for (index, item) in current.iter().enumerate() {
|
||||
if predicate(item.as_ref()) {
|
||||
found_index = Some(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(index) = found_index {
|
||||
let mut new_vec = current.as_ref().clone();
|
||||
let removed_item = new_vec.remove(index);
|
||||
|
||||
let new_arc = Arc::new(new_vec);
|
||||
|
||||
if self.inner.compare_and_swap(¤t, new_arc).is_ok() {
|
||||
return Some(removed_item);
|
||||
}
|
||||
// Retry si le CAS a échoué
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
if let Some(index) = found_index {
|
||||
let mut new_vec = current.as_ref().clone();
|
||||
let removed_item = new_vec.remove(index);
|
||||
self.inner.store(Arc::new(new_vec));
|
||||
Some(removed_item)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user